Main Page | Class Hierarchy | Class List | File List | Class Members | File Members | Related Pages

eap_parser.hxx

00001 /* BEGIN_COPYRIGHT                                                        */
00002 /*                                                                        */
00003 /* Open Diameter: Open-source software for the Diameter and               */
00004 /*                Diameter related protocols                              */
00005 /*                                                                        */
00006 /* Copyright (C) 2002-2004 Open Diameter Project                          */
00007 /*                                                                        */
00008 /* This library is free software; you can redistribute it and/or modify   */
00009 /* it under the terms of the GNU Lesser General Public License as         */
00010 /* published by the Free Software Foundation; either version 2.1 of the   */
00011 /* License, or (at your option) any later version.                        */
00012 /*                                                                        */
00013 /* This library is distributed in the hope that it will be useful,        */
00014 /* but WITHOUT ANY WARRANTY; without even the implied warranty of         */
00015 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU      */
00016 /* Lesser General Public License for more details.                        */
00017 /*                                                                        */
00018 /* You should have received a copy of the GNU Lesser General Public       */
00019 /* License along with this library; if not, write to the Free Software    */
00020 /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307    */
00021 /* USA.                                                                   */
00022 /*                                                                        */
00023 /* In addition, when you copy and redistribute some or the entire part of */
00024 /* the source code of this software with or without modification, you     */
00025 /* MUST include this copyright notice in each copy.                       */
00026 /*                                                                        */
00027 /* If you make any changes that are appeared to be useful, please send    */
00028 /* sources that include the changed part to                               */
00029 /* diameter-developers@lists.sourceforge.net so that we can reflect your  */
00030 /* changes to one unified version of this software.                       */
00031 /*                                                                        */
00032 /* END_COPYRIGHT                                                          */
00033 #ifndef  __EAP_PARSER_H__
00034 #define  __EAP_PARSER_H__
00035 
00036 #include "diameter_parser_api.h"
00037 #include "eap.hxx"
00038 #include "eap_log.hxx"
00039 
00041 typedef AAAParser<AAAMessageBlock*, EapHeader*> EapHeaderParser;
00042 
00047 inline void
00048 EapHeaderParser::parseRawToApp()
00049 {
00050   EapHeader *header = getAppData();
00051   AAAMessageBlock *buffer = getRawData();
00052   // Set the read pointer to the head of the buffer.
00053   buffer->rd_ptr(buffer->base());
00054 
00055   // read the code
00056   header->code = *buffer->rd_ptr(); buffer->rd_ptr(1);
00057 
00058   // read the identifier
00059   header->identifier = *buffer->rd_ptr(); buffer->rd_ptr(1);
00060 
00061   // read the length
00062   header->length = ntohs(*((ACE_UINT16*)buffer->rd_ptr())); 
00063   buffer->rd_ptr(sizeof(ACE_UINT16));
00064 }
00065 
00070 inline void
00071 EapHeaderParser::parseAppToRaw()
00072 {
00073   EapHeader *header = getAppData();
00074   AAAMessageBlock *buffer = getRawData();
00075   // Set the write pointer to the head of the buffer.
00076   buffer->wr_ptr(buffer->base());
00077 
00078   // write the code
00079   *buffer->wr_ptr() = header->code; buffer->wr_ptr(1);
00080 
00081   // write the identifier
00082   *buffer->wr_ptr() = header->identifier; buffer->wr_ptr(1);
00083 
00084   // write the length
00085   *((ACE_UINT16*)buffer->wr_ptr())
00086     = htons(header->length); buffer->wr_ptr(sizeof(ACE_UINT16));
00087 }
00088 
00090 typedef AAAParser<AAAMessageBlock*, EapRequest*> EapRequestParser;
00091 
00096 inline void
00097 EapRequestParser::parseRawToApp()
00098 {
00099   EapPayload *payload = getAppData();
00100   AAAMessageBlock *buffer = getRawData();
00101   EapRequest *request = (EapRequest*)payload;
00102 
00103   // Set the read pointer to the head of the payload.
00104   buffer->rd_ptr(buffer->base() + 4);
00105 
00106   // Read the type.
00107   ACE_Byte type = *buffer->rd_ptr(); 
00108   ACE_UINT16 vendorId;
00109   ACE_UINT16 vendorType;
00110   if (type == 254) // Vendor Specific Extension
00111     {
00112       vendorId=((ACE_UINT16)*buffer->rd_ptr() && 0x00ffffff);
00113       buffer->rd_ptr(4);
00114       vendorId = ntohs(vendorId);
00115       vendorType=(ACE_UINT16)*buffer->rd_ptr();
00116       vendorType = ntohs(vendorType);
00117       request->SetType(EapType(vendorId, vendorType));  
00118     }
00119   else
00120     {
00121       buffer->rd_ptr(1);
00122       request->SetType(EapType(type));
00123     }
00124 }
00125 
00132 inline void
00133 EapRequestParser::parseAppToRaw()
00134 {
00135   //EapPayload *payload = getAppData();
00136   AAAMessageBlock *buffer = getRawData();
00137   EapRequest *request = getAppData();
00138 
00139   // Set the read pointer to the head of the payload.
00140   buffer->wr_ptr(buffer->base() + 4);
00141 
00142   EapType eapType = request->GetType();
00143 
00144   // Write the type.
00145 
00146   if (eapType.type != 254) // Legacy type
00147     {
00148       buffer->copy((const char*)&eapType.type, 1);
00149     }
00150   else // Extended type
00151     {
00152       // Write vendor fields.
00153       ACE_UINT16 vid, vty;
00154       vid = (eapType.vendorId && 0x00ffffff) + (eapType.type << 24);
00155       vid = ntohs(vid);
00156       vty = ntohs(eapType.vendorType);
00157       buffer->copy((const char*)&vid, 4);
00158       buffer->copy((const char*)&vty, 4);
00159     }
00160 }
00161 
00162 
00164 class EAP_EXPORTS EapResponseParser: public EapRequestParser {};
00165 
00168 class EAP_EXPORTS EapNakDict
00169 {
00170 public:
00174   enum NakType {
00175     LegacyNak,
00176     ExtendedNak
00177   };
00178 
00179   EapNakDict(NakType type) : type(type) {}
00180 
00181   NakType type;
00182 };
00183 
00185 typedef AAAParser<AAAMessageBlock*, EapNak*, EapNakDict*> EapNakParser;
00186 
00191 inline void
00192 EapNakParser::parseRawToApp()
00193 {
00194   EapNakDict *d = getDictData();
00195   EapNak *nak = getAppData();
00196   AAAMessageBlock *msg = getRawData();
00197 
00198   EapTypeList &tList= nak->TypeList();
00199 
00200   if (d == NULL || d->type == EapNakDict::LegacyNak)    // legacy nak
00201     {
00202       EapTypeList::iterator i;
00203       
00204       for (i=tList.begin(); i!=tList.end(); i++)
00205         {
00206           ACE_Byte type = *msg->rd_ptr(); 
00207           msg->rd_ptr(1);
00208           tList.push_back(EapType(type));
00209         }
00210       return;
00211     }
00212   else  // extended nak
00213     {
00214       while (!msg->end())
00215         {
00216           // read the type.
00217           ACE_Byte type = *msg->rd_ptr(); 
00218           ACE_UINT16 vendorId;
00219           ACE_UINT16 vendorType;
00220           if (type == 254) // vendor specific type
00221             {
00222               vendorId=((ACE_UINT16)*msg->rd_ptr() && 0x00ffffff);
00223               msg->rd_ptr(4);
00224               vendorId = ntohs(vendorId);
00225               vendorType=(ACE_UINT16)*msg->rd_ptr();
00226               vendorType = ntohs(vendorType);
00227               if (vendorType != 3)  // extended Nak
00228                 tList.push_back(EapType(vendorId, vendorType));
00229             }
00230           else // legacy type
00231             {
00232               msg->rd_ptr(1);
00233               tList.push_back(EapType(type));
00234             }
00235         }
00236     }
00237 }
00238 
00246 inline void
00247 EapNakParser::parseAppToRaw()
00248 {
00249   EapNakDict *d = getDictData();
00250   EapNak *nak = getAppData();
00251   AAAMessageBlock *msg = getRawData();
00252 
00253   // Write type field
00254   EapResponseParser responseParser;
00255   responseParser.setRawData(msg);
00256   responseParser.setAppData(nak);
00257   responseParser.parseAppToRaw();     
00258 
00259   EapTypeList &tList= nak->TypeList();
00260 
00261   if (d == NULL || d->type == EapNakDict::LegacyNak)    // legacy nak
00262     {
00263       EapTypeList::iterator i;
00264       
00265       for (i=tList.begin(); i!=tList.end(); i++)
00266         {
00267           msg->copy((const char*)&(*i).type, 1);
00268         }
00269     }
00270 
00271   else // Extended nak
00272     {
00273       EapTypeList::iterator i;
00274       ACE_UINT32 vendorId, vendorType;
00275 
00276       // Set first entry (254,0,3)
00277       vendorId = (254 << 24);
00278       vendorId = ntohs(vendorId);
00279       vendorType = ntohs(3);
00280       msg->copy((const char*)&vendorId, 4);
00281       msg->copy((const char*)&vendorType, 4);
00282 
00283       // Set remaining ones.
00284       for (i=tList.begin(); i!=tList.end(); i++)
00285         {
00286           EapType t = *i;
00287 
00288           // Convert legacy type representation to vendor-specific
00289           // representation.
00290           if (t.type!=254)
00291             t = EapType(0, t.type);
00292 
00293           // Write vendor fields.
00294           vendorId = (t.vendorId && 0x00ffffff) | (t.type << 24);
00295           vendorId = ntohs(vendorId);
00296           vendorType = ntohs(t.vendorType);
00297           msg->copy((const char*)&vendorId, 4);
00298           msg->copy((const char*)&vendorType, 4);
00299         }
00300     }
00301 }
00302 
00304 typedef AAAParser<AAAMessageBlock*, EapIdentity*> 
00305 EapRequestIdentityParser;
00306 
00312 inline void
00313 EapRequestIdentityParser::parseRawToApp() 
00314 {
00315   AAAMessageBlock *msg = getRawData();
00316   EapIdentity *identity = getAppData();
00317   size_t idStringSize = msg->size() - (msg->rd_ptr()-msg->base());
00318 
00319   // UTF8 varidation without null-charater check.
00320   UTF8Checker check;
00321   if (check(msg->rd_ptr(), idStringSize) != 0)
00322     {
00323       EAP_LOG(LM_ERROR, "Invalid UTF8 string");
00324       throw -1;
00325     }
00326   std::string &str = identity->Identity();
00327   str.assign(msg->rd_ptr(), idStringSize);
00328   msg->rd_ptr(msg->end());
00329 }
00330 
00338 inline void
00339 EapRequestIdentityParser::parseAppToRaw()
00340 {
00341   AAAMessageBlock *msg = getRawData();
00342   EapIdentity *identity = getAppData();
00343 
00344   // Write type field
00345   EapResponseParser responseParser;
00346   responseParser.setRawData(msg);
00347   responseParser.setAppData(identity);
00348   responseParser.parseAppToRaw();     
00349 
00350   //  EapRequestParser::parseAppToRaw();     
00351   std::string &str = identity->Identity();
00352 
00353   UTF8Checker check;
00354   // UTF8 varidation with null-charater check.
00355   if (check(str.data(), str.size(), true) != 0)
00356     {
00357       EAP_LOG(LM_ERROR, "Invalid UTF8 string");
00358       throw -1;
00359     }
00360   msg->copy(str.data(), str.size());
00361 }
00362 
00364 class EAP_EXPORTS EapResponseIdentityParser: public EapRequestIdentityParser {};
00365 
00367 typedef AAAParser<AAAMessageBlock*, EapNotification*> 
00368 EapRequestNotificationParser;
00369 
00375 inline void
00376 EapRequestNotificationParser::parseRawToApp()
00377 {
00378   AAAMessageBlock *msg = getRawData();
00379   EapNotification *notification = getAppData();
00380   size_t notificationStringSize = msg->size() - (msg->rd_ptr()-msg->base());
00381 
00382   // UTF8 varidation without null-charater check.
00383   UTF8Checker check;
00384   if (check(msg->rd_ptr(), notificationStringSize) != 0)
00385     {
00386       EAP_LOG(LM_ERROR, "Invalid UTF8 string");
00387       throw -1;
00388     }
00389 
00390   std::string &str = notification->Notification();
00391   str.assign(msg->rd_ptr(), notificationStringSize);
00392   msg->rd_ptr(msg->end());
00393 }
00394 
00402 inline void
00403 EapRequestNotificationParser::parseAppToRaw()
00404 {
00405   AAAMessageBlock *msg = getRawData();
00406   EapNotification *notification = getAppData();
00407 
00408   // Write type field
00409   EapResponseParser responseParser;
00410   responseParser.setRawData(msg);
00411   responseParser.setAppData(notification);
00412   responseParser.parseAppToRaw();     
00413 
00414   //  EapRequestParser::parseAppToRaw();     
00415 
00416   std::string &str = notification->Notification();
00417   UTF8Checker check;
00418   // UTF8 varidation with null-charater check.
00419   if (check(str.data(), str.size(), true) != 0)
00420     {
00421       EAP_LOG(LM_ERROR, "Invalid UTF8 string");
00422       throw -1;
00423     }
00424 
00425   msg->copy(str.data(), str.size());
00426 }
00427 
00429 class EAP_EXPORTS EapResponseNotificationParser: public EapRequestIdentityParser 
00430 {};
00431 
00433 typedef AAAParser<AAAMessageBlock*, EapMD5Challenge*> 
00434 EapRequestMD5ChallengeParser;
00435 
00440 inline void
00441 EapRequestMD5ChallengeParser::parseRawToApp()
00442 {
00443   AAAMessageBlock *msg = getRawData();
00444   EapMD5Challenge *md5Challenge = getAppData();
00445   size_t contentSize = msg->size() - (msg->rd_ptr()-msg->base());
00446 
00447   // Read the Value-Size.
00448   ACE_Byte valueSize = (ACE_Byte)*msg->rd_ptr();
00449 
00450   msg->rd_ptr(1);
00451 
00452   // Read the Value.
00453   md5Challenge->Value().assign(msg->rd_ptr(), valueSize);
00454   msg->rd_ptr(valueSize);
00455 
00456   if (valueSize == 0)
00457     {
00458       EAP_LOG(LM_ERROR, "Empty value.");
00459       throw -1;
00460     }
00461 
00462   // Read the Name.
00463   ACE_INT16 nameLength = contentSize - (valueSize + 1); 
00464   md5Challenge->Name().assign(msg->rd_ptr(), nameLength);
00465   msg->rd_ptr(nameLength);
00466 }
00467 
00475 inline void
00476 EapRequestMD5ChallengeParser::parseAppToRaw()
00477 {
00478   AAAMessageBlock *msg = getRawData();
00479   EapMD5Challenge *md5Challenge = getAppData();
00480 
00481   // Write type field
00482   EapResponseParser responseParser;
00483   responseParser.setRawData(msg);
00484   responseParser.setAppData(md5Challenge);
00485   responseParser.parseAppToRaw();     
00486 
00487   //  EapRequestParser::parseAppToRaw();     
00488 
00489   ACE_Byte valueSize = md5Challenge->Value().size();
00490 
00491   // Check the value size.
00492   if (valueSize == 0)
00493     {
00494       EAP_LOG(LM_ERROR, "Empty value.");
00495       throw -1;
00496     }
00497 
00498   // Write the Value-Size.
00499   msg->copy((const char*)&valueSize, sizeof(valueSize));
00500 
00501   // Write the Value.
00502   msg->copy(md5Challenge->Value().data(), valueSize);
00503 
00504   // Write the Name.
00505   msg->copy(md5Challenge->Name().data(), md5Challenge->Name().size());
00506 }
00507 
00509 class EAP_EXPORTS EapResponseMD5ChallengeParser
00510   : public EapRequestMD5ChallengeParser 
00511 {};
00512 
00513 #endif // __EAP_PARSER_H__

Generated on Fri Jun 25 19:16:16 2004 for EAP State Machine by doxygen 1.3.5