📄 eap_tls_fsm.cxx
字号:
AddStateTableEntry(StBuildStart, StBuildStart, 0); AddStateTableEntry(StProcessResponseClientHello, EvSgInvalid, StInitialize, acNotifyInvalid); AddStateTableEntry(StProcessResponseClientHello, EvSgValid, StVerifyAuthMoreFragments, acVerifyAuthMoreFragments); AddStateTableEntry(StProcessResponseClientHello, EvSgAlertReceive, StFailure, acNotifyFailure); AddStateTableEntry(StProcessResponseClientHello, EvSgAlertSend, StBuildRequestAlert, acBuildRequestAlert); AddStateTableEntry(StBuildRequestAlert, EapMethodStateMachine::EvSgIntegrityCheck, StProcessResponseAckAlert, acProcessResponseAckAlert); AddStateTableEntry(StBuildRequestAlert, StBuildRequestAlert, 0); AddStateTableEntry(StProcessResponseAckAlert, EvSgInvalid, StInitialize, acNotifyInvalid); AddStateTableEntry(StProcessResponseAckAlert, EvSgValid, StFailure, acNotifyFailure); AddStateTableEntry(StVerifyAuthMoreFragments,EvSgMoreFragments, StRecvAck, acSendFragment); AddStateTableEntry(StVerifyAuthMoreFragments,EvSgNoMoreFragments, StProcessResponseSecondWay, acSendFragment); AddStateTableEntry(StVerifyAuthMoreFragments, EvSgInvalid, StInitialize, acNotifyInvalid); AddStateTableEntry(StRecvAck, EapMethodStateMachine::EvSgIntegrityCheck, StProcessResponseClientHello, acRecvAck); AddStateTableEntry(StRecvAck,StRecvAck, 0); AddStateTableEntry(StProcessResponseSecondWay, EapMethodStateMachine::EvSgIntegrityCheck, StVerifyPeerMoreFragments, acVerifyPeerMoreFragments); AddStateTableEntry(StProcessResponseSecondWay,StProcessResponseSecondWay, 0); AddStateTableEntry(StVerifyPeerMoreFragments, EvSgMoreFragments, StProcessResponseSecondWay, acSendAck); AddStateTableEntry(StVerifyPeerMoreFragments, EvSgNoMoreFragments, StSentRequestFinish, acProcessResponseSecondWay); AddStateTableEntry(StVerifyPeerMoreFragments, EvSgInvalid, StInitialize, acNotifyInvalid); AddStateTableEntry(StSentRequestFinish, EapMethodStateMachine::EvSgIntegrityCheck, StProcessResponseFinish, acProcessResponseFinish); AddStateTableEntry(StSentRequestFinish, StSentRequestFinish, 0); AddStateTableEntry(StSentRequestFinish, EvSgAlertReceive, StFailure, acNotifyFailure); AddStateTableEntry(StSentRequestFinish, EvSgAlertSend, StBuildRequestAlert, acBuildRequestAlert); AddStateTableEntry(StProcessResponseFinish, EvSgInvalid, StInitialize, acNotifyInvalid); AddStateTableEntry(StProcessResponseFinish, EvSgValid, StSuccess, acNotifySuccess); AddStateTableEntry(StProcessResponseFinish, EvSgAlertReceive, StFailure, acNotifyFailure); AddStateTableEntry(StProcessResponseFinish, EvSgAlertSend, StBuildRequestAlert, acBuildRequestAlert); AddStateTableEntry(StFailure, StFailure, 0); AddStateTableEntry(StSuccess, StSuccess, 0); InitialState(StInitialize); } // leaf class ~EapAuthTlsStateTable_S() {}};///---------------------------------------------------------------EapPeerTlsState--------------------------------------------------------------------/// State table used by EapPeerTlsStateMachine.class EAP_TLS_EXPORTS EapPeerTlsStateTable_S : public AAA_StateTable<EapPeerTlsStateMachine>{ friend class ACE_Singleton<EapPeerTlsStateTable_S, ACE_Recursive_Thread_Mutex>;private: class AcProcessStart : public EapPeerTlsAction { void operator()(EapPeerTlsStateMachine &msm) { EapPeerSwitchStateMachine &ssm = msm.PeerSwitchStateMachine(); EAPTLS_tls_mng_peer &tls_mng_peer = msm.get_mng_peer(); AAAMessageBlock *msg = ssm.GetRxMessage(); //Msg contains complete message.rd_ptr() points data section. (from byte after Type) and wr_ptr() at the end of Message EAP_LOG(LM_DEBUG, "PeerTls: Processing EAP-TLS Start.<-----------------\n"); // Check the EAP-TLS response. EapRequestTls request((ACE_Byte)0x00); EapRequestTlsParser parser; parser.setAppData(&request); parser.setRawData(msg); try { parser.parseRawToApp(); } catch (...) { EAP_LOG(LM_ERROR, "PeerTls: Parse error.\n"); msm.Event(EvSgInvalid); return; } EAPTLS_session_t_peer *session_peer = new EAPTLS_session_t_peer(msm.get_ctx_peer()); session_peer->session_init(false); msm.set_tls_session(session_peer); //Build a new session. session_peer->set_dirty_in(request.get_data()); tls_mng_peer.tls_handshake_recv(session_peer); msm.Event(EvSgValid); } }; class AcBuildResponseClientHello : public EapPeerTlsAction { void operator()(EapPeerTlsStateMachine &msm) { EapPeerSwitchStateMachine &ssm = msm.PeerSwitchStateMachine(); EAP_LOG(LM_DEBUG, "PeerTls: Building a Client Hello Message.--------------->\n"); EAPTLS_session_t_peer *session_peer = msm.get_tls_session(); AAAMessageBlock *data = session_peer->get_dirty_out(); //Getting TLS records to be encapsulated in request AAAMessageBlock *msg = AAAMessageBlock::Acquire(6+data->length()); //Code(1)+Identifier(1)+Length(2)+Type(1)+Flags(1)+ Data(n) EAP_LOG(LM_DEBUG, "PeeTls: data length %d\n",data->length()); ACE_OS::memset(msg->base(), 0, 6+data->length()); EapResponseTls response(0x00); EapResponseTlsParser parser; response.set_data(data); parser.setAppData(&response); parser.setRawData(msg); try { parser.parseAppToRaw(); } catch (...) { EAP_LOG(LM_ERROR, "PeerTls: Parse error.\n"); msm.Event(EvSgInvalid); return; } // Set the message to the session. ssm.SetTxMessage(msg); // Update external method state. ssm.MethodState() = EapPeerSwitchStateMachine::CONT; // Send a "valid" signal to the switch state machine. ssm.Event(EapPeerSwitchStateMachine::EvSgValidReq); } }; class AcVerifyAuthMoreFragments : public EapPeerTlsAction { void operator()(EapPeerTlsStateMachine &msm) { EapPeerSwitchStateMachine &ssm = msm.PeerSwitchStateMachine(); EAPTLS_session_t_peer *session_peer = msm.get_tls_session(); EAPTLS_tls_mng_peer &tls_mng_peer = msm.get_mng_peer(); AAAMessageBlock *msg = ssm.GetRxMessage(); //msg->wr_ptr(msg->end()); EAP_LOG(LM_DEBUG, "-------------->PeerTls: Verify Auth More Fragments.\n"); ACE_UINT32 state = 0; EapResponseTls response((ACE_Byte)0x00); EapResponseTlsParser parser; parser.setAppData(&response); parser.setRawData(msg); try { parser.parseRawToApp(); } catch (...) { EAP_LOG(LM_ERROR, "PeerTls: Parse error.\n"); msm.Event(EvSgInvalid); return; } static bool first_fragment = true; if (TLS_MORE_FRAGMENTS(response.get_flags())) //This variable could be true if it is not fragmented or it is first fragmented { EAP_LOG(LM_DEBUG,"PeerTls : AUTH MORE_FRAGMENTS\n"); if (TLS_LENGTH_INCLUDED(response.get_flags()) && first_fragment) //There is no fragments { if (response.get_tls_message_length() > 0) { session_peer->set_dirty_in(response.get_data()); first_fragment = false; state=EvSgMoreFragments; } else state=EvSgInvalid; } else if (!TLS_LENGTH_INCLUDED(response.get_flags()) && !first_fragment) { if (response.get_data()->length() > 0) { state=EvSgMoreFragments; session_peer->append_dirty_in(response.get_data()); } else state=EvSgInvalid; } else state = EvSgInvalid; } else { first_fragment ? session_peer->set_dirty_in(response.get_data()) : session_peer->append_dirty_in(response.get_data()); first_fragment = true; ACE_INT32 err; if((err = tls_mng_peer.tls_handshake_recv(session_peer)) == EAPTLS_tls_mng::StAlertReceive) {EAP_LOG(LM_ERROR, "PeerTls: AcProcessRequestSecondWay: AlertReceive.\n"); msm.Event(EvSgAlertReceive); return; } else if (err == EAPTLS_tls_mng::StAlertSend) {EAP_LOG(LM_ERROR, "PeerTls: AcProcessRequestFinish: AlertSend.\n"); msm.Event(EvSgAlertSend); return; } else //It is a packet without fragmentation. state = EvSgNoMoreFragments; } msm.Event(state); } }; class AcSendAck: public EapPeerTlsAction { void operator()(EapPeerTlsStateMachine &msm) { EapPeerSwitchStateMachine &ssm = msm.PeerSwitchStateMachine(); EAP_LOG(LM_DEBUG, "<----------- PeerTls: Send ACK.\n"); AAAMessageBlock *msg = AAAMessageBlock::Acquire(5+1); //[Code(1) + identifier (1) + length(2) + type(1)] + flags(1) ACE_OS::memset(msg->base(), 0, 5+1); EapRequestTls request(0x00); //A request with S bit enabled. EapRequestTlsParser parser; parser.setAppData(&request); parser.setRawData(msg); try { parser.parseAppToRaw(); } catch (...) { EAP_LOG(LM_ERROR, "AuthTls: Parse error.\n"); msm.Event(EvSgInvalid); return; } // Set the message to the session. ssm.SetTxMessage(msg); // Update external method state. ssm.MethodState() = EapPeerSwitchStateMachine::CONT; // Send a "valid" signal to the switch state machine. ssm.Notify(EapPeerSwitchStateMachine::EvSgValidReq); } }; class AcVerifyPeerMoreFragments : public EapPeerTlsAction { void operator()(EapPeerTlsStateMachine &msm) { ACE_Byte flags=0x00; ACE_UINT32 state=0; EAP_LOG(LM_DEBUG, "<--------------PeerTls: Verify Peer More Fragments.\n"); EAPTLS_session_t_peer *session_peer = msm.get_tls_session(); AAAMessageBlock *data = session_peer->get_dirty_out(); //Getting TLS records to be encapsulated in request ACE_INT32 length_to_send=data->length()+6; //+6 (Header length) =//Code(1)+Identifier(1)+Length(2)+Type(1)+Flags(1)+Data(n) ACE_INT32 length_fragment=session_peer->get_fragment_size(); static bool first_fragment=true; if ((length_fragment != 0) && (length_fragment < length_to_send)) { EAP_LOG(LM_DEBUG,"PeerTls : MORE FRAGMENTS \n"); length_to_send = length_fragment; //We need to send more fragments flags = SET_MORE_FRAGMENTS(flags); if (first_fragment) { EAP_LOG(LM_DEBUG,"PeerTls : LENGTH INCLUDED\n"); flags = SET_LENGTH_INCLUDED(flags); first_fragment=false; } state = EvSgMoreFragments; } else { EAP_LOG(LM_DEBUG,"PeerTls : NO MORE FRAGMENTS \n"); state = EvSgNoMoreFragments; first_fragment=true; //Restore first fragment value; } session_peer->set_length_to_send(length_to_send); //Length will be sent by next state. session_peer->set_flags_to_send(flags); msm.Event(state); } }; class AcSendFragment : public EapPeerTlsAction { void operator()(EapPeerTlsStateMachine &msm) { EapPeerSwitchStateMachine &ssm = msm.PeerSwitchStateMachine(); EAP_LOG(LM_DEBUG, "<--------------PeerTls: Send Fragment.\n"); EAPTLS_session_t_peer *session_peer = msm.get_tls_session(); AAAMessageBlock *data = session_peer->get_dirty_out(); //Getting TLS records to be encapsulated in request ACE_INT32 length_to_send=session_peer->get_length_to_send(); ACE_Byte flags=session_peer->get_flags_to_send(); EAP_LOG(LM_ERROR, "PeerTls: LENGTH TO SEND %d.\n",length_to_send); AAAMessageBlock *msg = AAAMessageBlock::Acquire(length_to_send); ACE_OS::memset(msg->base(), 0, length_to_send); EapRequestTls request(flags); request.set_data(data); EapRequestTlsParser parser; parser.setAppData(&request); parser.setRawData(msg); try { parser.parseAppToRaw(); } catch (...) { EAP_LOG(LM_ERROR, "PeerTls: Parse error.\n"); msm.Event(EvSgInvalid); return; } if (TLS_LENGTH_INCLUDED(flags)) data->rd_ptr(length_to_send-6-4);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -