📄 pana_paa.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 */#include "pana_paa.h"#include "pana_config_manager.h"#include "pana_cookie.h"#include "pana_sid_generator.h"#include "pana_pmk_bootstrap.h"PANA_Paa::PANA_Paa(PANA_SessionTxInterface &tp, PANA_SessionTimerInterface &tm, PANA_PaaEventInterface &ev) : PANA_Session(tp, tm, ev) { // resolve Pac device id PANA_DeviceIdContainer &localAddrs = m_TxChannel.GetLocalAddress(); PANA_DeviceId *id = localAddrs.search(AAA_ADDR_FAMILY_802); if (id == NULL) { id = PANA_DeviceIdConverter::GetIpOnlyAddress(localAddrs, (bool)PANA_CFG_GENERAL().m_IPv6Enabled); if (id) { PaaIpAddress().set_addr((void*)id->value.data(), id->value.size(), 0); } } if (id) { PaaDeviceId() = *id; } else { throw (PANA_Exception(PANA_Exception::FAILED, "No device ID available")); } // ------------------------------ // State: OFFLINE (Initial State) // ------------------------------ // // Initialization Action: // // USE_COOKIE=Set|Unset; // PIGGYBACK=Set|Unset; // SEPARATE=Set|Unset; // if (PIGGYBACK==Set) // SEPARATE=Unset; // MOBILITY=Set|Unset; // 1ST_EAP=Unset; // ABORT_ON_1ST_EAP_FAILURE=Set|Unset; // CARRY_LIFETIME=Set|Unset; // CARRY_EP_DEVICE_ID=Set|Unset; // CARRY_NAP_INFO=Set|Unset; // CARRY_ISP_INFO=Set|Unset; // CARRY_PPAC=Set|Unset; // PROTECTION_CAP_IN_PSR=Set|Unset; // PROTECTION_CAP_IN_PBR=Set|Unset; // if (PROTECTION_CAP_IN_PBR==UnSet) // PROTECTION_CAP_IN_PSR=Unset // else // CARRY_DEVICE_ID=Set; // NAP_AUTH=Unset; // RTX_COUNTER=0; // RtxTimerStop(); Reset(); // generate a new session id diameter_octetstring_t sid; PANA_SESSIONID_GENERATOR().Generate(sid); SessionId().assign(sid.data(), sid.size()); // Local reset PreferedNAP().m_Id = PANA_CFG_PAA().m_NapInfo.m_Id; PreferedNAP().m_Name = PANA_CFG_PAA().m_NapInfo.m_Name; if (! PANA_CFG_PAA().m_UseCookie && PANA_CFG_GENERAL().m_EapPiggyback) { AuxVariables().SeparateAuthentication() = false; } m_Flags.p = 0; m_Flags.i.CarryPcapInPSR = PANA_CARRY_PCAP_IN_PSR; m_Flags.i.CarryPcapInPBR = (PANA_CFG_GENERAL().m_ProtectionCap >= 0) ? true : PANA_CARRY_PCAP_IN_PBR; if (! m_Flags.i.CarryPcapInPBR) { m_Flags.i.CarryPcapInPSR = false; } else { AuxVariables().CarryDeviceId() = true; } AuxVariables().NapAuthentication() = false;}void PANA_Paa::NotifyAuthorization(){ PANA_SessionEventInterface::PANA_AuthorizationArgs args; args.m_Pac.Set(PacDeviceId()); args.m_Paa.Set(PaaDeviceId()); if (SecurityAssociation().IsSet()) { args.m_Key.Set(SecurityAssociation().Get()); // TBD: key id removed from args if (PPAC().DhcpV6() && DhcpBootstrap().Enable()) { diameter_octetstring_t dhcpKey; DhcpBootstrap().DhcpKey(SecurityAssociation().Get(), dhcpKey); args.m_DhcpKey.Set(dhcpKey); } if (PANA_CFG_GENERAL().m_WPASupport && (PANA_CFG_PAA().m_EpIdList.size() > 0)) { PANA_DeviceIdIterator i; for (i = PANA_CFG_PAA().m_EpIdList.begin(); i != PANA_CFG_PAA().m_EpIdList.end(); i ++) { PANA_DeviceId *epId = (*i); PANA_PMKKey pmk(SecurityAssociation().Get(), PacDeviceId().value, epId->value); args.m_PMKKeyList().push_back(pmk.Key()); } if (PANA_CFG_PAA().m_EpIdList.size() > 0) { args.m_PMKKeyList.IsSet() = true; } } } args.m_Lifetime.Set(SessionLifetime()); args.m_ProtectionCapability.Set(ProtectionCapability()); args.m_Ep.Set(&PANA_CFG_PAA().m_EpIdList); args.m_PreferedISP.Set(PreferedISP()); args.m_PreferedNAP.Set(PreferedNAP()); m_Event.Authorize(args);}void PANA_Paa::NotifyEapRestart(){ bool napAuth = false; m_Event.EapStart(napAuth); AuxVariables().NapAuthentication() = false;}void PANA_Paa::NotifyEapResponse(diameter_octetstring_t &payload){ AAAMessageBlock *block = AAAMessageBlock::Acquire(payload.size()); if (block) { block->copy((char*)payload.data(), payload.size()); block->wr_ptr(block->base()); static_cast<PANA_PaaEventInterface&> (m_Event).EapResponse(block, AuxVariables().NapAuthentication()); block->Release(); }}void PANA_Paa::NotifyEapTimeout(){ TxPER(PANA_UNABLE_TO_COMPLY); Disconnect(PANA_UNABLE_TO_COMPLY);}void PANA_Paa::NotifyEapReAuth(){ bool napAuth = false; m_Event.EapStart(napAuth); if (AuxVariables().SeparateAuthentication()) { AuxVariables().NapAuthentication() = napAuth; } AuxVariables().FirstEapResult() = 0; m_Timer.CancelSession();}bool PANA_Paa::IsUserAuthorized(){ bool IsAuth = static_cast<PANA_PaaEventInterface&> (m_Event).IsUserAuthorized(); return (AuxVariables().Authorized() = IsAuth);}void PANA_Paa::TxPSR(){ /* 7.2 PANA-Start-Request (PSR) The PANA-Start-Request (PSR) message is sent by the PAA to the PaC to advertise availability of the PAA and start PANA authentication. The PAA sets the sequence number to an initial random value. PANA-Start-Request ::= < PANA-Header: 2, REQ [,SEP] > [ Nonce ] [ Cookie ] [ EAP-Payload ] [ NAP-Information ] * [ ISP-Information ] [ Algorithm ] [ Protection-Capability] [ PPAC ] [ Notification ] * [ AVP ] */ boost::shared_ptr<PANA_Message> msg(new PANA_Message); // Populate header msg->type() = PANA_MTYPE_PSR; msg->flags().request = true; msg->flags().separate = AuxVariables().SeparateAuthentication(); // adjust serial num ++ LastTxSeqNum(); msg->seq() = LastTxSeqNum().Value(); // add paa nonce SecurityAssociation().PaaNonce().Generate(); diameter_octetstring_t &nonce = SecurityAssociation().PaaNonce().Get(); AAA_StringAvpWidget nonceAvp(PANA_AVPNAME_NONCE); nonceAvp.Get().assign(nonce.data(), nonce.size()); msg->avpList().add(nonceAvp()); // add eap payload if (! AuxVariables().TxEapMessageQueue().Empty()) { PANA_MsgBlockGuard eapPkt(AuxVariables().TxEapMessageQueue().Dequeue()); AAA_StringAvpWidget eapAvp(PANA_AVPNAME_EAP); eapAvp.Get().assign(eapPkt()->base(), eapPkt()->size()); msg->avpList().add(eapAvp()); msg->flags().separate = false; } // add ppac if (PANA_CFG_GENERAL().m_PPAC() > 0) { AAA_UInt32AvpWidget ppacAvp(PANA_AVPNAME_PPAC); ppacAvp.Get() = ACE_HTONL(PANA_CFG_GENERAL().m_PPAC()); msg->avpList().add(ppacAvp()); } // add protection capability if (SupportFlags().i.CarryPcapInPSR) { AAA_UInt32AvpWidget pcapAvp(PANA_AVPNAME_PROTECTIONCAP); pcapAvp.Get() = ACE_HTONL(PANA_CFG_GENERAL().m_ProtectionCap); msg->avpList().add(pcapAvp()); } // add nap information if (PANA_CFG_PAA().m_NapInfo.m_Id > 0) { AAA_GroupedAvpWidget napAvp(PANA_AVPNAME_NAPINFO); PANA_ProviderInfoTool infoTool; infoTool.Add(napAvp.Get(), PreferedNAP()); msg->avpList().add(napAvp()); } // add ISP information if (! PANA_CFG_PAA().m_IspInfo.empty()) { PANA_CfgProviderList::iterator i; AAA_GroupedAvpWidget ispAvp(PANA_AVPNAME_ISPINFO); for (i = PANA_CFG_PAA().m_IspInfo.begin(); i != PANA_CFG_PAA().m_IspInfo.end(); i++) { PANA_ProviderInfoTool infoTool; infoTool.Add(ispAvp.Get(), *(*i)); } msg->avpList().add(ispAvp()); } // add notification if any AddNotification(*msg); /* Protection-Capability and Post-PANA-Address-Configuration AVPs MAY be optionally included in the PANA-Start-Request in order to indicate required and available capabilities for the network access. These AVPs MAY be used by the PaC for assessing the capability match even before the authentication takes place. But these AVPs are provided during the insecure discovery phase, there are certain security risks involved in using the provided information. See Section 9 for further discussion on this. ... ... In networks where lower-layers are not secured prior to running PANA, the capability discovery enabled through inclusion of Protection-Capability and Post-PANA-Address-Configuration AVPs in a PANA-Start-Request message is susceptible to spoofing leading to denial-of service attacks. Therefore, usage of these AVPs during the discovery and initial handshake phase in such insecure networks is NOT RECOMMENDED. The same AVPs are delivered via an integrity-protected PANA-Bind-Request upon successful authentication. */ ACE_DEBUG((LM_INFO, "(%P|%t) TxPSR: S-flag %d, N-flag=%d, seq=%d\n", msg->flags().separate, msg->flags().nap, msg->seq())); SendReqMsg(msg);}void PANA_Paa::RxPSA(){ /* 7.3 PANA-Start-Answer (PSA) The PANA-Start-Answer (PSA) message is sent by the PaC to the PAA in response to a PANA-Start-Request message. This message completes the handshake to start PANA authentication. PANA-Start-Answer ::= < PANA-Header: 2 [,SEP] > [ Nonce ] [ Cookie ] [ EAP-Payload ] [ ISP-Information ] [ Notification ] * [ AVP ] */ std::auto_ptr<PANA_Message> cleanup(AuxVariables().RxMsgQueue().Dequeue()); PANA_Message &msg = *cleanup; ACE_DEBUG((LM_INFO, "(%P|%t) RxPSA: S-flag %d, N-flag=%d, seq=%d\n", msg.flags().separate, msg.flags().nap, msg.seq())); // update pac nonce AAA_StringAvpContainerWidget nonceAvp(msg.avpList()); diameter_octetstring_t *nonce = nonceAvp.GetAvp(PANA_AVPNAME_NONCE); if (nonce &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -