📄 diameter_eap_server_fsm.cxx
字号:
/* BEGIN_COPYRIGHT *//* *//* Open Diameter: Open-source software for the Diameter and *//* Diameter related protocols *//* *//* Copyright (C) 2002-2004 Open Diameter Project *//* *//* This library is free software; you can redistribute it and/or modify *//* it under the terms of the GNU Lesser General Public License as *//* published by the Free Software Foundation; either version 2.1 of the *//* License, or (at your option) any later version. *//* *//* This library 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 *//* Lesser General Public License for more details. *//* *//* You should have received a copy of the GNU Lesser General Public *//* License along with this library; 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 */// $Id: diameter_eap_server_fsm.cxx,v 1.28 2004/08/16 16:17:25 vfajardo Exp $// diameter_eap_server_fsm.cxx: EAP session handling// Written by Yoshihiro Ohba#include <ace/Singleton.h>#include <ace/Atomic_Op_T.h>#include "diameter_eap_server_session.hxx"#include "diameter_eap_server_fsm.hxx"#include "diameter_eap_parser.hxx"class DiameterEapServerAction : public AAA_Action<DiameterEapServerStateMachine>{ virtual void operator()(DiameterEapServerStateMachine&)=0; protected: DiameterEapServerAction() {} ~DiameterEapServerAction() {}};/// State table used by DiameterEapServerStateMachine.class DiameterEapServerStateTable_S : public AAA_StateTable<DiameterEapServerStateMachine>{ friend class ACE_Singleton<DiameterEapServerStateTable_S, ACE_Recursive_Thread_Mutex>; private: class AcForwardEapResponse : public DiameterEapServerAction { void operator()(DiameterEapServerStateMachine& sm) { AAA_LOG(LM_DEBUG, "[%N] forwarding EAP Response to authenticator.\n"); sm.ForwardEapResponse(sm.DER().EapPayload()); } }; class AcCheckDER : public DiameterEapServerAction { void operator()(DiameterEapServerStateMachine& sm) { AAA_LOG(LM_DEBUG, "[%N] Copying DER to DEA.\n"); if (sm.CheckDER()) sm.Event(DiameterEapServerStateMachine::EvSgValidDER); else sm.Event(DiameterEapServerStateMachine::EvSgInvalidDER); } }; class AcSendDEAwithContinue : public DiameterEapServerAction { void operator()(DiameterEapServerStateMachine& sm) { DiameterEapServerSession& session = sm.Session(); AAA_LOG(LM_DEBUG, "[%N] Sending DEA with continue result-code.\n"); // Set Result-Code to AAA_MULTI_ROUND_AUTH. DEA_Data& dea = sm.DEA(); dea.ResultCode = AAA_MULTI_ROUND_AUTH; // Set reply message if needed. dea.ReplyMessage.Clear(); sm.SetReplyMessage(dea.ReplyMessage, dea.ResultCode()); dea.EapReissuedPayload.Clear(); sm.SetReissuedEapPayload(dea.EapReissuedPayload); sm.SendDEA(); // Update the session state. session.Update(AAASession::EVENT_AUTH_CONTINUE); } }; class AcSendDEAwithSuccess : public DiameterEapServerAction { void operator()(DiameterEapServerStateMachine& sm) { AAA_LOG(LM_DEBUG, "[%N] Sending DEA with a success Result-Code.\n"); DiameterEapServerSession& session = sm.Session(); DEA_Data& dea = sm.Session().DEA(); dea.ResultCode = AAA_SUCCESS; sm.SendDEA(); session.Update(AAASession::EVENT_AUTH_SUCCESS); } }; class AcSendDEA_DueToAuthenticationFailure : public DiameterEapServerAction { void operator()(DiameterEapServerStateMachine& sm) { DiameterEapServerSession& session = sm.Session(); DEA_Data& dea = sm.Session().DEA(); AAA_LOG(LM_DEBUG, "[%N] Sending DEA due to authentication failure.\n"); dea.ResultCode = AAA_AUTHENTICATION_REJECTED; sm.SendDEA(); session.Update(AAASession::EVENT_AUTH_FAILED); } }; class AcSendDEA_DueToAuthorizationFailure : public DiameterEapServerAction { void operator()(DiameterEapServerStateMachine& sm) { DiameterEapServerSession& session = sm.Session(); DEA_Data& dea = sm.Session().DEA(); AAA_LOG(LM_DEBUG, "[%N] Sending DEA due to authorization failure.\n"); // Erase EAP payload since it may contain EAP Success message // when authentication is successful but authorization fails. dea.EapPayload.Clear(); dea.ResultCode = AAA_AUTHORIZATION_REJECTED; sm.SendDEA(); session.Update(AAASession::EVENT_AUTH_FAILED); } }; class AcSendDEA_DueToInvalidDER : public DiameterEapServerAction { void operator()(DiameterEapServerStateMachine& sm) { DiameterEapServerSession& session = sm.Session(); DEA_Data& dea = sm.DEA(); AAA_LOG(LM_DEBUG, "[%N] Sending DEA due to invalid DER.\n"); dea.ResultCode = AAA_INVALID_AVP_VALUE; session.Update(AAASession::EVENT_AUTH_CONTINUE); sm.SendDEA(); } }; class AcAuthorize : public DiameterEapServerAction { void operator()(DiameterEapServerStateMachine& sm) { if (sm.AuthorizationDone() || sm.Authorize()) sm.Event(DiameterEapServerStateMachine::EvSgAuthorizationSuccess); else sm.Event(DiameterEapServerStateMachine::EvSgAuthorizationFailure); } }; enum state { StInitialize, StWaitDER, StCheckDER, StWaitAuthorization, StAccepted, StRejected, StWaitEapMsg, StTerminated }; enum { EvSgSuccess, EvSgLimitedSuccess, EvSgFailure, EvSgContinue, EvSgValid, EvSgInvalid }; AcSendDEAwithContinue acSendDEAwithContinue; AcSendDEAwithSuccess acSendDEAwithSuccess; AcSendDEA_DueToAuthenticationFailure acSendDEA_DueToAuthenticationFailure; AcSendDEA_DueToAuthorizationFailure acSendDEA_DueToAuthorizationFailure; AcSendDEA_DueToInvalidDER acSendDEA_DueToInvalidDER; AcForwardEapResponse acForwardEapResponse; AcCheckDER acCheckDER; AcAuthorize acAuthorize; // Defined as a leaf class DiameterEapServerStateTable_S() { AddStateTableEntry(StInitialize, DiameterEapServerStateMachine::EvRxDER, StCheckDER, acCheckDER); AddStateTableEntry(StInitialize, DiameterEapServerStateMachine::EvSgDisconnect, StTerminated); AddWildcardStateTableEntry(StInitialize, StTerminated); AddStateTableEntry(StCheckDER, DiameterEapServerStateMachine::EvSgValidDER, StWaitEapMsg, acForwardEapResponse); AddStateTableEntry(StCheckDER, DiameterEapServerStateMachine::EvSgInvalidDER, StRejected, acSendDEA_DueToInvalidDER); AddStateTableEntry(StWaitDER, DiameterEapServerStateMachine::EvRxDER, StCheckDER, acCheckDER); AddStateTableEntry(StWaitDER, DiameterEapServerStateMachine::EvSgDisconnect, StTerminated); AddWildcardStateTableEntry(StWaitDER, StTerminated); AddStateTableEntry(StWaitEapMsg, DiameterEapServerStateMachine::EvRxEapRequest, StWaitDER, acSendDEAwithContinue); AddStateTableEntry(StWaitEapMsg, DiameterEapServerStateMachine::EvRxEapSuccess, StWaitAuthorization, acAuthorize); AddStateTableEntry(StWaitEapMsg, DiameterEapServerStateMachine::EvRxEapFailure, StRejected, acSendDEA_DueToAuthenticationFailure); AddStateTableEntry(StWaitEapMsg, DiameterEapServerStateMachine::EvSgDisconnect, StTerminated); AddWildcardStateTableEntry(StWaitEapMsg, StTerminated); AddStateTableEntry(StWaitAuthorization, DiameterEapServerStateMachine::EvSgAuthorizationSuccess, StAccepted, acSendDEAwithSuccess); AddStateTableEntry(StWaitAuthorization, DiameterEapServerStateMachine::EvSgAuthorizationFailure, StRejected, acSendDEA_DueToAuthorizationFailure); AddStateTableEntry(StWaitAuthorization, DiameterEapServerStateMachine::EvSgDisconnect, StTerminated); AddWildcardStateTableEntry(StWaitAuthorization, StTerminated); // Re-authentication AddStateTableEntry(StAccepted, DiameterEapServerStateMachine::EvRxDER, StCheckDER, acCheckDER); AddStateTableEntry(StAccepted, DiameterEapServerStateMachine::EvSgDisconnect, StTerminated); AddWildcardStateTableEntry(StAccepted, StTerminated); AddWildcardStateTableEntry(StRejected, StRejected); AddWildcardStateTableEntry(StTerminated, StTerminated); InitialState(StInitialize); } ~DiameterEapServerStateTable_S() {}};typedef ACE_Singleton<DiameterEapServerStateTable_S, ACE_Recursive_Thread_Mutex> DiameterEapServerStateTable;DiameterEapServerStateMachine::DiameterEapServerStateMachine(DiameterEapServerSession& s, DiameterJobHandle &h) : AAA_StateMachine<DiameterEapServerStateMachine> (*this, *DiameterEapServerStateTable::instance(), "AAA_EAP_CLIENT"), session(s), handle(h), authorizationDone(false){}void DiameterEapServerStateMachine::SendDEA(){ AAAMessage msg; deaData.AuthApplicationId = EapApplicationId; DEA_Parser parser; parser.setAppData(&session.deaData); parser.setRawData(&msg); try { parser.parseAppToRaw(); } catch (DiameterParserError) { AAA_LOG(LM_ERROR, "[%N] Parsing error.\n"); return; } AAAMessageControl msgControl(session.Self()); if (msgControl.Send(msg) != AAA_ERR_SUCCESS) { AAA_LOG(LM_ERROR, "Failed sending message.\n"); } else { AAA_LOG(LM_DEBUG, "Sent DEA Message.\n"); }}boolDiameterEapServerStateMachine::CheckDER(){ DER_Data& der = derData; DEA_Data& dea = deaData; // Auth-Request-Type check. if (der.AuthRequestType() != AUTH_REQUEST_TYPE_AUTHENTICATION_ONLY && der.AuthRequestType() != AUTH_REQUEST_TYPE_AUTHORIZE_AUTHENTICATE) { AAA_LOG(LM_ERROR, "[%N] Invalid auth request type.\n"); return false; } dea.AuthRequestType = der.AuthRequestType; AuthorizeMultiRoundTimeOut(dea.MultiRoundTimeOut); if (!dea.AuthRequestType.IsSet()) { AAA_LOG(LM_ERROR, "[%N] Failed to set auth request type.\n"); return false; } // Class check. for (unsigned i=0; i<dea.Class.size(); i++) { bool found = false; for (unsigned j=0; j<der.Class.size(); j++) { if (dea.Class[i] == der.Class[j])
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -