📄 eap_tls_fsm.cxx
字号:
/* BEGIN_COPYRIGHT *//* *//* Open Diameter: Open-source software for the Diameter and *//* Diameter related protocols *//* *//* Copyright (C) 2002-2004 Open Diameter Project *//* *//* This program is free software; you can redistribute it and/or modify *//* it under the terms of the GNU General Public License as published by *//* the Free Software Foundation; either version 2 of the License, or *//* (at your option) any later version. *//* */ /* This program is distributed in the hope that it will be useful, *//* but WITHOUT ANY WARRANTY; without even the implied warranty of *//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *//* GNU General Public License for more details. *//* *//* You should have received a copy of the GNU General Public License *//* along with this program; if not, write to the Free Software *//* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *//* USA. *//* *//* In addition, when you copy and redistribute some or the entire part of *//* the source code of this software with or without modification, you *//* MUST include this copyright notice in each copy. *//* *//* If you make any changes that are appeared to be useful, please send *//* sources that include the changed part to *//* diameter-developers@lists.sourceforge.net so that we can reflect your *//* changes to one unified version of this software. *//* *//* END_COPYRIGHT *//*************************************************************************** eap_tls_fsm.cxx - description ------------------- begin : jue mar 18 2004 copyright : (C) 2004 by email : ***************************************************************************//*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/#include "eap_tls_fsm.hxx"#define VALUE_TIME 1/// Action class.class EapPeerTlsAction : public AAA_Action<EapPeerTlsStateMachine>{ public: virtual void operator()(EapPeerTlsStateMachine&) {} protected: EapPeerTlsAction() {} virtual ~EapPeerTlsAction() {}};/// Action class.class EapAuthTlsAction : public AAA_Action<EapAuthTlsStateMachine>{ public: virtual void operator()(EapAuthTlsStateMachine&) {} protected: EapAuthTlsAction() {} virtual ~EapAuthTlsAction() {}};/// State table used by EapAuthTlsStateMachine.class EAP_TLS_EXPORTS EapAuthTlsStateTable_S: public AAA_StateTable<EapAuthTlsStateMachine>{ friend class ACE_Singleton<EapAuthTlsStateTable_S, ACE_Recursive_Thread_Mutex>;private: class AcBuildStart : public EapAuthTlsAction { void operator()(EapAuthTlsStateMachine &msm) { EapAuthSwitchStateMachine &ssm = msm.AuthSwitchStateMachine(); EAP_LOG(LM_DEBUG, "<----------- AuthTls: Building a Start message.\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(SET_START(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; } EAPTLS_session_t_auth *session_auth = new EAPTLS_session_t_auth(msm.get_ctx_auth()); session_auth->session_init(false); msm.set_tls_session(session_auth); //Build a new session. //sleep(VALUE_TIME); //msm.History().append(msg->base() + 4, 1); // Set the message to the session. ssm.SetTxMessage(msg); // Send a "valid" signal to the switch state machine. ssm.Notify(EapAuthSwitchStateMachine::EvSgValidResp); } }; class AcProcessResponseClientHello : public EapAuthTlsAction { void operator()(EapAuthTlsStateMachine &msm) { EapAuthSwitchStateMachine &ssm = msm.AuthSwitchStateMachine(); EAPTLS_tls_mng_auth &tls_mng_auth = msm.get_mng_auth(); 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 msg->wr_ptr(msg->end()); EAP_LOG(LM_DEBUG, "------------->AuthTls: Processing EAP-TLS client hello.%d\n",msg->length()); // Check the EAP-TLS response. EapResponseTls response((ACE_Byte)0x00); EapResponseTlsParser parser; parser.setAppData(&response); parser.setRawData(msg); try { parser.parseRawToApp(); } catch (...) { EAP_LOG(LM_ERROR, "AuthTls: Parse error.\n"); msm.Event(EvSgInvalid); return; } EAPTLS_session_t_auth *session_auth = msm.get_tls_session(); session_auth->set_dirty_in(response.get_data()); //sleep(VALUE_TIME); ACE_INT32 err; if((err = tls_mng_auth.tls_handshake_recv(session_auth)) == EAPTLS_tls_mng::StAlertReceive) {EAP_LOG(LM_ERROR, "AuthTls: AcProcessResponseClienteHello: AlertReceive.\n"); msm.Event(EvSgAlertReceive); } else if (err == EAPTLS_tls_mng::StAlertSend) {EAP_LOG(LM_ERROR, "AuthTls: AcProcessResponseClienteHello: AlertSend.\n"); msm.Event(EvSgAlertSend); } else msm.Event(EvSgValid); } }; class AcVerifyAuthMoreFragments : public EapAuthTlsAction { void operator()(EapAuthTlsStateMachine &msm) { ACE_Byte flags=0x00; ACE_UINT32 state=0; EAP_LOG(LM_DEBUG, "<--------------AuthTls: Verify Auth more fragments.\n"); EAPTLS_session_t_auth *session_auth = msm.get_tls_session(); AAAMessageBlock *data = session_auth->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_auth->get_fragment_size(); //bool length_included=session_auth->if_length_included(); static bool first_fragment=true; if ((length_fragment != 0) && (length_fragment < length_to_send)) { EAP_LOG(LM_DEBUG,"AUTH: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,"AUTH: FIRST FRAGMENT\n"); flags = SET_LENGTH_INCLUDED(flags); first_fragment = false; } state = EvSgMoreFragments; } else { state = EvSgNoMoreFragments; first_fragment=true; //Restore first fragment value; EAP_LOG(LM_DEBUG,"AUTH: NO FRAGMENTS\n"); } session_auth->set_length_to_send(length_to_send); //Length will be sent by next state. session_auth->set_flags_to_send(flags); msm.Event(state); } }; class AcSendFragment : public EapAuthTlsAction { void operator()(EapAuthTlsStateMachine &msm) { EapAuthSwitchStateMachine &ssm = msm.AuthSwitchStateMachine(); EAP_LOG(LM_DEBUG, "<--------------AuthTls: Send Fragment.\n"); EAPTLS_session_t_auth *session_auth = msm.get_tls_session(); AAAMessageBlock *data = session_auth->get_dirty_out(); //Getting TLS records to be encapsulated in request ACE_UINT32 length_to_send=session_auth->get_length_to_send(); ACE_Byte flags=session_auth->get_flags_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, "AuthTls: Parse error.\n"); msm.Event(EvSgInvalid); return; } if (TLS_LENGTH_INCLUDED(flags)) data->rd_ptr(length_to_send-6-4); else data->rd_ptr(length_to_send-6); //Move pointer to next bytes (next future fragment) EAP_LOG(LM_DEBUG,"LENGTH NEXT FRAGMENT %d\n",data->length()); // Set the message to the session. ssm.SetTxMessage(msg); // Send a "valid" signal to the switch state machine. ssm.Notify(EapAuthSwitchStateMachine::EvSgValidResp); } }; class AcRecvAck : public EapAuthTlsAction { void operator()(EapAuthTlsStateMachine &msm) { EapAuthSwitchStateMachine &ssm = msm.AuthSwitchStateMachine(); 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, "AuthTls: Processing ACK.\n"); // Check the EAP-TLS response. 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; } if (response.get_is_ack()) msm.Event(EvSgValid); else msm.Event(EvSgInvalid); } }; class AcSendAck: public EapAuthTlsAction { void operator()(EapAuthTlsStateMachine &msm) { EapAuthSwitchStateMachine &ssm = msm.AuthSwitchStateMachine(); EAP_LOG(LM_DEBUG, "<----------- AuthTls: 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); // Send a "valid" signal to the switch state machine. ssm.Notify(EapAuthSwitchStateMachine::EvSgValidResp); } }; class AcVerifyPeerMoreFragments : public EapAuthTlsAction { void operator()(EapAuthTlsStateMachine &msm) { EapAuthSwitchStateMachine &ssm = msm.AuthSwitchStateMachine(); EAPTLS_session_t_auth *session_auth = msm.get_tls_session(); AAAMessageBlock *msg = ssm.GetRxMessage(); msg->wr_ptr(msg->end()); EAP_LOG(LM_DEBUG, "-------------->AutTls: Verify Peer More Fragments.\n"); ACE_UINT32 state = 0; ACE_UINT32 length_fragment = 0; EapResponseTls response((ACE_Byte)0x00); EapResponseTlsParser parser; parser.setAppData(&response); parser.setRawData(msg); try { parser.parseRawToApp(); } catch (...) { EAP_LOG(LM_ERROR, "AuthTls: Parse error.\n"); msm.Event(EvSgInvalid); return; } static bool first_fragment = true; AAAMessageBlock *data=response.get_data(); if (data != NULL) length_fragment=data->length(); else length_fragment = 0; //if (data == NULL) EAP_LOG(LM_DEBUG,"Without data\n"); 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,"AuthTls : MORE FRAGMENTS \n"); if (TLS_LENGTH_INCLUDED(response.get_flags()) && first_fragment) //There is no fragments { EAP_LOG(LM_DEBUG,"AuthTls : LENGTH INCLUDED \n"); length_fragment = response.get_tls_message_length();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -