📄 eap_passthrough_authfsm.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: eap_passthrough_authfsm.cxx,v 1.22 2004/09/29 15:42:43 yohba Exp $// eap_passthrough_authfsm.cxx: Passthrough Authenticator state machine// Written by Yoshihiro Ohba#include <ace/Basic_Types.h>#include <ace/Singleton.h>#include "eap.hxx"#include "eap_authfsm.hxx"#include "eap_policy.hxx"#include "eap_log.hxx"#include "eap_parser.hxx"/// Action class for EAP. class EapPassThroughAuthSwitchAction : public AAA_Action<EapPassThroughAuthSwitchStateMachine>{ public: virtual void operator()(EapPassThroughAuthSwitchStateMachine&) {} protected: EapPassThroughAuthSwitchAction() {} virtual ~EapPassThroughAuthSwitchAction() {}};/// State table used by EapAuthSwitchStateMachine.class EapPassThroughAuthSwitchStateTable_S : public AAA_StateTable<EapPassThroughAuthSwitchStateMachine>{ friend class ACE_Singleton<EapPassThroughAuthSwitchStateTable_S, ACE_Recursive_Thread_Mutex>;private: class AcDisable : public EapPassThroughAuthSwitchAction { void operator()(EapPassThroughAuthSwitchStateMachine &sm) { sm.Event(EapAuthSwitchStateMachine::EvSgPortEnabled); } }; class AcInitialize : public EapPassThroughAuthSwitchAction { void operator()(EapPassThroughAuthSwitchStateMachine &sm) { sm.CurrentIdentifier() = 0; // Initilize the identifier sm.Event(EvUCT); } }; class AcSendSuccess : public EapPassThroughAuthSwitchAction { void operator()(EapPassThroughAuthSwitchStateMachine &sm) { AAAMessageBlock *msg = AAAMessageBlock::Acquire(4); EAP_LOG(LM_DEBUG, "Passthrough: Composing Success message.\n"); // Compose the PDU. EapHeaderParser parser; EapHeader header; header.code = Success; header.identifier = sm.CurrentIdentifier(); header.length = 4; parser.setAppData(&header); parser.setRawData(msg); parser.parseAppToRaw(); // Stop retransmission timer and reset retransmission counter. sm.CancelTimer(); sm.RetransmissionCount()=0; // Make the key available. (not specified in the state machine document.) if (sm.KeyData().size()>0) sm.KeyAvailable() = true; // Call Success callback function. sm.Success(msg); msg->release(); } }; class AcSendFailure : public EapPassThroughAuthSwitchAction { void operator()(EapPassThroughAuthSwitchStateMachine &sm) { AAAMessageBlock *msg = AAAMessageBlock::Acquire(4); EAP_LOG(LM_DEBUG, "Passthrough: Composing Failure message.\n"); // Compose the PDU. EapHeaderParser parser; EapHeader header; header.code = Failure; header.identifier = sm.CurrentIdentifier(); header.length = 4; parser.setAppData(&header); parser.setRawData(msg); parser.parseAppToRaw(); // Stop retransmission timer and reset retransmission counter. sm.CancelTimer(); sm.RetransmissionCount()=0; // Call Failure callback function. sm.Failure(msg); msg->release(); } }; class AcMethodResponse : public EapPassThroughAuthSwitchAction { void operator()(EapPassThroughAuthSwitchStateMachine &sm) { EapMethodStateMachine &msm = sm.MethodStateMachine(); if (msm.IsDone()) { sm.KeyData() = msm.KeyData(); sm.MethodState() = EapAuthSwitchStateMachine::END; sm.Event(EapAuthSwitchStateMachine::EvSgEndMethod); } else { sm.MethodState() = EapAuthSwitchStateMachine::CONT; sm.Event(EvElse); } } }; class AcBuildRequest : public EapPassThroughAuthSwitchAction { void operator()(EapPassThroughAuthSwitchStateMachine &sm) { // Calculate the next Identifier for the new request. ACE_Byte id = sm.CurrentIdentifier() = sm.MethodStateMachine().GetNextIdentifier(sm.CurrentIdentifier()); AAAMessageBlock *msg = sm.GetTxMessage(); // Compose the PDU. EapHeaderParser headerParser; EapHeader header; header.code = Request; header.identifier = id; header.length = msg->length(); headerParser.setAppData(&header); headerParser.setRawData(msg); headerParser.parseAppToRaw(); // Set the wr_ptr to the tail of the message. msg->wr_ptr(msg->base()+header.length); sm.Event(EvUCT); } }; class AcSendRequest : public EapPassThroughAuthSwitchAction { void operator()(EapPassThroughAuthSwitchStateMachine &sm) { // Stop retransmission timer and reset retransmission counter. sm.CancelTimer(); sm.RetransmissionCount()=0; AAAMessageBlock *msg = sm.GetTxMessage(); // Call Send callback function. // Increment the retransmission count. sm.RetransmissionCount()++; // Schedule retransmssion timer EAP_LOG(LM_DEBUG, "Passthrough: Request sent and timer started.\n"); if (sm.RetransmissionEnabled()) sm.ScheduleTimer(EvTo, sm.RetransmissionInterval()); sm.Notify(EvUCT); // Send the messsage. sm.Send(msg); } }; class AcDoIntegrityCheck : public EapPassThroughAuthSwitchAction { void operator()(EapPassThroughAuthSwitchStateMachine &sm) { EAP_LOG(LM_DEBUG, "Passthrough: Integrity Check.\n"); sm.MethodStateMachine().Notify (EapMethodStateMachine::EvSgIntegrityCheck); } }; class AcProposeMethod : public EapPassThroughAuthSwitchAction { void operator()(EapPassThroughAuthSwitchStateMachine &sm) { EapType type = sm.Policy().CurrentMethod(); if (!type.IsVSE()) EAP_LOG(LM_DEBUG, "PassThrough: Trying a legacy method.\n"); else EAP_LOG(LM_DEBUG, "PassThrough: Trying an extended method.\n"); sm.DeleteMethodStateMachine(); sm.CurrentMethod() = type; sm.CreateMethodStateMachine(type, Authenticator); sm.MethodStateMachine().Start(); if (type == EapType(1) || type == EapType(2)) // Identity or Notification sm.MethodState() = EapAuthSwitchStateMachine::CONT; else sm.MethodState() = EapAuthSwitchStateMachine::PROPOSED; // Notify method sm.MethodStateMachine().Notify (EapMethodStateMachine::EvSgIntegrityCheck); } }; class AcDoPolicyCheck : public EapPassThroughAuthSwitchAction { void operator()(EapPassThroughAuthSwitchStateMachine &sm) { EapAuthSwitchStateMachine::EapAuthDecision decision = sm.Decision(); if (decision == EapAuthSwitchStateMachine::DecisionSuccess) sm.Event(EvSgPolicySat); else if (decision == EapAuthSwitchStateMachine::DecisionFailure) sm.Event(EvSgPolicyNotSat_EndSess); else if (decision == EapAuthSwitchStateMachine::DecisionPassthrough) sm.Event(EvSgPassThrough); else // continue sm.Event(EvElse); } }; class AcDiscard : public EapPassThroughAuthSwitchAction { void operator()(EapPassThroughAuthSwitchStateMachine &sm) { EAP_LOG(LM_DEBUG, "Passthrough: Message Discarded.\n"); sm.DiscardCount()++; sm.Event(EvUCT); } }; class AcDiscard2 : public EapPassThroughAuthSwitchAction { void operator()(EapPassThroughAuthSwitchStateMachine &sm) { EAP_LOG(LM_DEBUG, "Passthrough: Message discarded without parsing.\n"); sm.DiscardCount()++; AAAMessageBlock *msg; EapMessageQueue &q = sm.RxQueue(); // Dequeue a message from receiving queue. q.dequeue_head((ACE_Message_Block*&)msg); // Release it. msg->release(); sm.Event(EvUCT); } }; class AcDiscard3 : public EapPassThroughAuthSwitchAction { void operator()(EapPassThroughAuthSwitchStateMachine &sm) { EAP_LOG(LM_DEBUG, "Passthrough: Message Discarded.\n"); AAAMessageBlock *msg; EapMessageQueue &q = sm.AAARxQueue(); // Dequeue a message from receiving queue. q.dequeue_head((ACE_Message_Block*&)msg); msg->release(); } }; class AcResetMethod : public EapPassThroughAuthSwitchAction { void operator()(EapPassThroughAuthSwitchStateMachine &sm) { AAAMessageBlock *msg=sm.GetRxMessage(); EAP_LOG(LM_DEBUG, "Passthrough: Reset method due to receiving Nak.\n"); // Parse the nak EapNakParser parser; EapNak nak; parser.setDictData(NULL); parser.setAppData(&nak); parser.setRawData(msg); parser.parseRawToApp(); sm.DeleteRxMessage(); // Update policy based on type list. EAP_LOG(LM_DEBUG, "Passthrough: Update policy on Nak.\n"); sm.Policy().Update(nak.TypeList()); sm.Event(EvUCT); } }; class AcRetransmit : public EapPassThroughAuthSwitchAction { void operator()(EapPassThroughAuthSwitchStateMachine &sm) { if (sm.RetransmissionCount() < sm.MaxRetransmissionCount()) { EAP_LOG(LM_DEBUG, "Passthrough: Retransmitting Request.\n"); // Get the message to retransmit. AAAMessageBlock *msg = sm.GetTxMessage(); // Call Send callback function. // Increment the retransmission count sm.RetransmissionCount()++; sm.Notify(EvElse); // Execute the callback function for sending the messsage // cb->Send(msg); sm.Send(msg); } else { EAP_LOG(LM_ERROR, "AuthSwitch: Reach max retransmission count.\n"); sm.CancelTimer(); sm.Event(EvSgMaxRetransmission); } } }; class AcReceiveMsg : public EapPassThroughAuthSwitchAction { void operator()(EapPassThroughAuthSwitchStateMachine &sm) { AAAMessageBlock *msg; // Dequeue a message from receiving queue. sm.RxQueue().dequeue_head((ACE_Message_Block*&)msg); // Set the read pointer to the message head. msg->rd_ptr(msg->base()); // Set msg to rxMessage. sm.SetRxMessage(msg); // Parse the header EapHeaderParser hp; EapHeader header; hp.setAppData(&header); hp.setRawData(msg); hp.parseRawToApp(); // Check code unsigned code = header.code; unsigned id = header.identifier; // Check code & identifier if ((code != Response) || (id != sm.CurrentIdentifier())) { sm.DeleteRxMessage(); sm.Notify(EvElse); return; } // Parse the response EapResponseParser parser; EapResponse resp; parser.setAppData(&resp); parser.setRawData(msg); parser.parseRawToApp(); EapType type = sm.CurrentMethod(); // Check response type. If this is a Nak message and the current // method is not a pass-through method, then generate a Nak // reception event. if (resp.GetType() == EapType(3) && sm.Decision() != EapAuthSwitchStateMachine::DecisionPassthrough) { if (sm.MethodState() == EapAuthSwitchStateMachine::PROPOSED) { sm.Event(EvRxNak); } else { sm.DeleteRxMessage(); sm.Event(EvElse); } } else // Normal method { if (resp.GetType() != type && sm.Decision() != EapAuthSwitchStateMachine::DecisionPassthrough) { sm.DeleteRxMessage(); sm.Event(EvElse); } else { sm.Event(EvRxMethodResp); } } } }; class AcReceiveMsg2 : public EapPassThroughAuthSwitchAction { void operator()(EapPassThroughAuthSwitchStateMachine &sm) { AAAMessageBlock *msg; // Dequeue a message from receiving queue. sm.RxQueue().dequeue_head((ACE_Message_Block*&)msg); // Set the read pointer to the message head. msg->rd_ptr(msg->base()); // Set msg to rxMessage. sm.SetRxMessage(msg); // Parse the header EapHeaderParser hp; EapHeader header; hp.setAppData(&header); hp.setRawData(msg); hp.parseRawToApp(); // Check code unsigned code = header.code; unsigned id = header.identifier; // Check code & identifier if ((code != Response) || (id != sm.CurrentIdentifier())) { sm.DeleteRxMessage(); sm.Notify(EvElse); return; } sm.Event(EvRxMethodResp); } }; class AcPickUpInitCheck : public EapPassThroughAuthSwitchAction { void operator()(EapPassThroughAuthSwitchStateMachine &sm) { if (sm.GetRxMessage()==0) sm.Event(EvSgNoPickUpInit); else sm.Event(EvSgPickUpInit); } };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -