00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef __EAP_FSM_HXX__
00039 #define __EAP_FSM_HXX__
00040
00041 #include <ace/Basic_Types.h>
00042 #include <ace/Singleton.h>
00043 #include <ace/Synch.h>
00044 #include <ace/Event_Handler.h>
00045 #include <list>
00046 #include <utility>
00047 #include "framework.h"
00048 #include "eap.hxx"
00049 #include "eap_log.hxx"
00050 #include "eap_policy.hxx"
00051
00052 typedef AAA_JobHandle< AAA_GroupedJob > EapJobHandle;
00053
00058 class EapJobMultiplexor : public AAA_JobQueueJob
00059 {
00060 public:
00061 EapJobMultiplexor(EapJobHandle& h) : handle(h)
00062 {}
00063 ~EapJobMultiplexor() { handle.Job().Remove(this); }
00064
00065 void Flush()
00066 {
00067 AAA_JobQueueJob::Flush();
00068 handle.Job().Remove(this);
00069 }
00070
00071 int Serve()
00072 {
00073 if (!ExistBacklog())
00074 {
00075 EAP_LOG(LM_ERROR, "%N: no backlog to serve.");
00076 return 0;
00077 }
00078
00079 AAA_Job *job;
00080 Dequeue(job);
00081 bool existBacklog = ExistBacklog();
00082 job->Serve();
00083 return existBacklog;
00084 }
00085
00086
00087 int Schedule(AAA_Job* job, size_t=1)
00088 {
00089 Enqueue(job);
00090 return handle.Job().Schedule(this);
00091 }
00092
00093 inline AAA_JobData& JobData() { return *handle.Job().Data(); }
00094
00095 template <class T> inline T& JobData(Type2Type<T>)
00096 { return (T&)*handle.Job().Data(); }
00097
00098 private:
00099
00101 EapJobHandle handle;
00102 };
00103
00114 template <class ARG>
00115 class EapStateMachine :
00116 public AAA_StateMachineWithTimer<ARG>,
00117 private AAA_EventQueueJob
00118 {
00119 public:
00121 EapStateMachine(ARG& arg, AAA_StateTable<ARG> &table, ACE_Reactor &r,
00122 EapJobMultiplexor &mux, char *name=0)
00123 : AAA_StateMachineWithTimer<ARG>(arg, table, r, name),
00124 mux(mux)
00125 {}
00126
00127 void Stop()
00128 {
00129 AAA_StateMachineWithTimer<ARG>::Stop();
00130 mux.Flush();
00131 }
00132
00134 inline int Serve()
00135 {
00136
00137 AAA_Event ev;
00138 AAA_EventQueueJob::Dequeue(ev);
00139
00140 bool existBacklog = AAA_EventQueueJob::ExistBacklog();
00141
00142
00143 Event(ev);
00144 return existBacklog ? 1 : 0;
00145 }
00146
00148 inline void Timeout(AAA_Event ev) { Notify(ev); }
00149
00150
00151
00152 inline void Notify(AAA_Event ev) throw (int) {
00153
00154 if (AAA_EventQueueJob::Enqueue(ev) <= 0)
00155 throw -1;
00156
00157
00158 if (mux.Schedule(this) < 0)
00159 throw -1;
00160 }
00161
00162 private:
00163
00164 int Schedule(AAA_Job*, size_t=1) { return (-1); }
00165
00166 EapJobMultiplexor& mux;
00167 };
00168
00169 typedef ACE_Message_Queue<ACE_MT_SYNCH> EapMessageQueue;
00170
00172 class EapMethodStateMachine;
00173
00198
00199 class EAP_EXPORTS EapSwitchStateMachine : public EapJobMultiplexor
00200 {
00201 public:
00202
00204 virtual void Notify(AAA_Event ev)=0;
00205
00212 virtual void Send(AAAMessageBlock *b)=0;
00213
00218 virtual void Abort()=0;
00219
00221 inline EapType& CurrentMethod() { return currentMethod; }
00222
00224 virtual void Receive(AAAMessageBlock*)=0;
00225
00228 virtual void ReceiveFromAAA(AAAMessageBlock *msg) throw(int)
00229 {
00230 EAP_LOG(LM_ERROR, "ReceiveFromAAA Operation not allowed.");
00231 throw -1;
00232 }
00233
00235 inline ACE_Byte& CurrentIdentifier() { return currentIdentifier; }
00236
00239
00240 inline AAAMessageBlock* GetRxMessage() {return rxMessage; }
00241
00244 inline void SetRxMessage(AAAMessageBlock *p) {
00245 if (rxMessage) rxMessage->release();
00246 rxMessage=p;
00247 }
00248
00251 inline void DeleteRxMessage() { SetRxMessage(0); }
00252
00255 inline AAAMessageBlock* GetTxMessage() { return txMessage; }
00256
00259 inline void SetTxMessage(AAAMessageBlock *p) {
00260 if (txMessage) txMessage->release();
00261 txMessage=p;
00262 }
00263
00266 inline void DeleteTxMessage() { SetTxMessage(0); }
00267
00269 inline std::string& PeerIdentity() { return peerIdentity; }
00270
00273 inline std::string& AuthenticatorIdentity()
00274 { return authenticatorIdentity; }
00275
00277 inline bool& KeyAvailable() { return keyAvailable; }
00278
00280 inline std::string& KeyData() { return keyData; }
00281
00283 bool IsEapTunneled() { return eapTunneled; }
00284
00286 inline EapPolicy& Policy(void) { return policy; }
00287
00290 void CreateMethodStateMachine(EapType t, EapRole role);
00291
00294 void DeleteMethodStateMachine();
00295
00297 inline EapMethodStateMachine& MethodStateMachine()
00298 { return *methodStateMachine; }
00299
00301 EapMessageQueue& RxQueue() { return rxQueue; }
00302
00304 int& DiscardCount() { return discardCount; }
00305
00306 ACE_Reactor& Reactor() { return reactor; }
00307
00308 protected:
00309 EapSwitchStateMachine(ACE_Reactor &r, EapJobHandle &h) :
00310 EapJobMultiplexor(h),
00311 currentMethod(EapType(0)),
00312 txMessage(0), rxMessage(0), eapTunneled(false),
00313 methodStateMachine(0), discardCount(0), keyAvailable(false),
00314 reactor(r)
00315 {
00316 keyData.resize(0);
00317 }
00318
00319 virtual ~EapSwitchStateMachine()
00320 {
00321 DeleteMethodStateMachine();
00322 DeleteRxMessage();
00323 DeleteTxMessage();
00324 }
00325
00327 EapType currentMethod;
00328
00333 AAAMessageBlock *txMessage;
00334
00337 AAAMessageBlock *rxMessage;
00338
00340 EapMessageQueue rxQueue;
00341
00344 ACE_Byte currentIdentifier;
00345
00350 std::string peerIdentity;
00351
00356 std::string authenticatorIdentity;
00357
00360 bool eapTunneled;
00361
00363 EapPolicy policy;
00364
00366 EapMethodStateMachine* methodStateMachine;
00367
00369 int discardCount;
00370
00372 bool keyAvailable;
00373
00375 std::string keyData;
00376
00377 ACE_Reactor &reactor;
00378 };
00379
00380 class EapPeerSwitchStateMachine;
00381 class EapAuthSwitchStateMachine;
00382
00411
00412 class EAP_EXPORTS EapMethodStateMachine
00413 {
00414 public:
00415
00416 virtual ~EapMethodStateMachine() {}
00417
00420 virtual void Start() throw(AAA_Error)=0;
00421
00424 virtual void Notify(AAA_Event)=0;
00425
00427 inline bool KeyAvailable() { return (keyData.size()>0); }
00428
00430 inline std::string& KeyData() { return keyData; }
00431
00433 inline AAA_JobData& JobData() { return switchStateMachine.JobData(); }
00434
00435 template <class T> inline T& JobData(Type2Type<T>)
00436 { return switchStateMachine.JobData(t); }
00437
00439 bool& IsDone() { return isDone; }
00440
00442 inline EapSwitchStateMachine& SwitchStateMachine()
00443 { return switchStateMachine; }
00444
00447 virtual ACE_Byte GetNextIdentifier(ACE_Byte id) { return id + 1; }
00448
00450 enum event {
00451 EvSgIntegrityCheck=-1,
00452 };
00453
00456 inline EapPeerSwitchStateMachine& PeerSwitchStateMachine()
00457 {
00458 return (EapPeerSwitchStateMachine&)switchStateMachine;
00459 }
00460
00463 inline EapAuthSwitchStateMachine& AuthSwitchStateMachine()
00464 {
00465 return (EapAuthSwitchStateMachine&)switchStateMachine;
00466 }
00467
00468 template <class T>
00469 inline T& SwitchStateMachine(Type2Type<T>)
00470 { return (T&)switchStateMachine; }
00471
00472 protected:
00473 EapMethodStateMachine(EapSwitchStateMachine &s)
00474 : switchStateMachine(s), isDone(false)
00475 {
00476 keyData.resize(0);
00477 }
00478
00479
00481 EapSwitchStateMachine& switchStateMachine;
00482
00486 bool isDone;
00487
00491 std::string keyData;
00492
00493 private:
00494 };
00495
00496 #endif // __EAP_FSM_HXX__