hostapd EAP状态机变迁代码分析

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/NJZhuJinhua/article/details/6991085


朱金华 Nov.19, 2011 周六 家中

转载请注明

jinhua1982@gmail.com



搜遍google,baidu,sogou,关于EAP 状态机的信息,除了搜到本博客以前几篇的结构定义分析, 基本没有什么关于eap状态机的描述了,近期有需要给项目讲下状态机,特梳理及做代码分析如下:


EAP状态机在RFC4137中描述, 其中介绍了4种状态机,分别是Peer SM, StandAlone SM, Backend SM和Full/Passthrough.

[Peer]<----->[StandAlone] 就是双方交互模型

[Peer]<----->[Passthrough SM]<------>Backend Server就是三方的了, Backend收到的肯定是从passthrough那边, 一般就是NAS发来的了


.


SM_STEP(EAP):

为总的状态机的循环及分支判断逻辑.里面的各个case实际是从哪个状态而来的, 根据其结果决定后续进入哪个新状态.


SM_STATE(EAP, INITIALIZE):
主要是些初始化工作
sm->currentId = -1;
sm->eap_if.eapSuccess = FALSE;
sm->eap_if.eapFail = FALSE;
sm->eap_if.eapTimeout = FALSE;
os_free(sm->eap_if.eapKeyData);
sm->eap_if.eapKeyData = NULL;
sm->eap_if.eapKeyDataLen = 0;
sm->eap_if.eapKeyAvailable = FALSE;
sm->eap_if.eapRestart = FALSE;
以及在当前为backend时对响应报文进行分拣parse的操作.
根据parse的结果, 
如果为backend且无eapresp则进入selectAction, 如果有resp但是pmethod为NAK,则后续进入NAK, 否则进入PICK_UP_METHOD.这也是BACKEND状态机与standalone的区别,即少了retransment, 多了INITIALIZE阶段的对nas开始的method的"pick up"操作.
如果不是backend,则进入的是"SM_ENTER(EAP, SELECT_ACTION)".


SM_STATE(EAP, PICK_UP_METHOD):
调用eap_sm_Policy_doPickUp
此函数的实现仅是简单比较当前的respmethod 是否为EAP_TYPE_IDENTITY,如真则返回TRUE.
如果函数返回为T, 则当前的method设为respmethod, 并调用eap_server_get_eap_method得到method相关指针并做相关初始化操作.
doPickUp上面已完成,这里只是比较下上面的结果以便决定后续流程, 如果当前method为EAP_TYPE_NONE则进入SM_ENTER(EAP, SELECT_ACTION);
否则是SM_ENTER(EAP, METHOD_RESPONSE)开始正常处理响应.


SM_STATE(EAP, METHOD_RESPONSE):
本状态内调用选定method的process方法. 对于正常情况来说,此时走到这里是pickup 的nas发来的eap-identity方法, 则调用identity方法的process处理而已
process完成之后调用该方法的idDone判断. 如果该method已结束,则设置sm->methodState = METHOD_END否则设置sm->methodState = METHOD_CONTINUE




在执行完上述过程后,有多种分支共选择, 其中还提供了eap的pending等待机制, 
/*
* Note: Mechanism to allow EAP methods to wait while going
* through pending processing is an extension to RFC 4137
* which only defines the transits to SELECT_ACTION and
* METHOD_REQUEST from this METHOD_RESPONSE state.
*/
if (sm->methodState == METHOD_END)
//如果method已结束, 后续进入SELECT_ACTION状态
SM_ENTER(EAP, SELECT_ACTION);
else if (sm->method_pending == METHOD_PENDING_WAIT) {
//状态不再变化, 状态机的运转暂时退出, 保留当前的状态
wpa_printf(MSG_DEBUG, "EAP: Method has pending "
"processing - wait before proceeding to "
"METHOD_REQUEST state");
} else if (sm->method_pending == METHOD_PENDING_CONT) {
//状态机重新执行时从此开始, 且继续运行, 正常情况是继续处理eapresp消息.
wpa_printf(MSG_DEBUG, "EAP: Method has completed "
"pending processing - reprocess pending "
"EAP message");
sm->method_pending = METHOD_PENDING_NONE;
SM_ENTER(EAP, METHOD_RESPONSE);
} else
//状态机正常运行中,处理发送eap请求消息
SM_ENTER(EAP, METHOD_REQUEST);
break;


SM_STATE(EAP, SELECT_ACTION)
进入此状态,调用eap_sm_Policy_getDecision将取得如下返回值
enum {
DECISION_SUCCESS, DECISION_FAILURE, DECISION_CONTINUE,
DECISION_PASSTHROUGH
} decision;


其中backend状态机是没有DECISION_PASSTHROUGH的
此函数内, 需要取得当前支持的鉴权算法, 原来代码是每个用户支持不同的算法集的, 在此时就查的用户信息的, 这个可以修改为通用的配置,或其他策略.


因为identity方法的结束, 流程进入SELECT_ACTION状态后, 这里会产生4条后续路径.
if (sm->decision == DECISION_FAILURE)
SM_ENTER(EAP, FAILURE);
else if (sm->decision == DECISION_SUCCESS)
SM_ENTER(EAP, SUCCESS);
else if (sm->decision == DECISION_PASSTHROUGH)
SM_ENTER(EAP, INITIALIZE_PASSTHROUGH);
else
SM_ENTER(EAP, PROPOSE_METHOD);
如下图所示,图为backend的状态机的一部分,因而PASSTHROUTH的路线没有画出.
如果此时既未SUCCESS,也未FAILURE,则进入红色的else,即PROPOSE_METHOD状态.

 


SM_STATE(EAP, PROPOSE_METHOD):
首先调用eap_sm_Policy_getNextMethod,
eap_sm_Policy_getNextMethod主要为了得到下一步需要的method,其实现:1如果identity此时为空,则继续identity方法.
2:否则选择支持的算法的下一个method
3:如果选取不到则结束


选择好method后, 调用该method的init回调函数,并设置状态为METHOD_PROPOSED,之后进入SM_STATE(EAP, METHOD_REQUEST)




SM_STATE(EAP, METHOD_REQUEST):
获取nextid, 并生成eap req报文.


SM_STATE(EAP, SEND_REQUEST):
设置有eap req的数据及其标志


进入IDLE,状态机无变化,然后退出.
待下层接口检测到有reqData时发送eap 请求报文.


收到响应后,状态从EAP_IDLE转变为EAP_RECEIVED


SM_STATE(EAP, RECEIVED):
调用eap_sm_parseEapResp
分析收到的消息头,包括是否是响应, respId, respMethod是什么等,


进一步开始下一步分支选择, 
如果id匹配,且respMethod为EAP_TYPE_NAK,则进入NAK状态,里面会发起eap_sm_Policy_update, 即算法重选的.
如果respmeth就是本server的method,则进入SM_ENTER(EAP, INTEGRITY_CHECK)进行完整性检查.


SM_STATE(EAP, INTEGRITY_CHECK):
如果选定的method实现有check回调函数,则调用,用于消息校验.


校验的结果赋值为状态机sm的ignore变量.
如果此变量为TRUE, 则进入DISCARD状态,执行丢弃处理
否则成功后进入SM_ENTER(EAP, METHOD_RESPONSE)


SM_STATE(EAP, METHOD_RESPONSE):
前面有说明, 做选定method的process处理
process之后会有isDone的检查用于设定methodState是METHOD_END还是METHOD_CONTINUE


如果为METHOD_END则继续执行SELECT_ACTION 否则继续进入METHOD_REQUEST状态发送请求消息.收到response后进入另一轮RECEIVE
在SELECT_ACTION的时候, 会有检查该method是否success的isSuccess调用,如果为真,得到的decision为DICISION_SUCCESS, 接着状态机将进入SM_ENTER(EAP, SUCCESS),否则若FAILURE,进入的就是SM_ENTER(EAP, FAILURE)了
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值