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 #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
00053 buffer->rd_ptr(buffer->base());
00054
00055
00056 header->code = *buffer->rd_ptr(); buffer->rd_ptr(1);
00057
00058
00059 header->identifier = *buffer->rd_ptr(); buffer->rd_ptr(1);
00060
00061
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
00076 buffer->wr_ptr(buffer->base());
00077
00078
00079 *buffer->wr_ptr() = header->code; buffer->wr_ptr(1);
00080
00081
00082 *buffer->wr_ptr() = header->identifier; buffer->wr_ptr(1);
00083
00084
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
00104 buffer->rd_ptr(buffer->base() + 4);
00105
00106
00107 ACE_Byte type = *buffer->rd_ptr();
00108 ACE_UINT16 vendorId;
00109 ACE_UINT16 vendorType;
00110 if (type == 254)
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
00136 AAAMessageBlock *buffer = getRawData();
00137 EapRequest *request = getAppData();
00138
00139
00140 buffer->wr_ptr(buffer->base() + 4);
00141
00142 EapType eapType = request->GetType();
00143
00144
00145
00146 if (eapType.type != 254)
00147 {
00148 buffer->copy((const char*)&eapType.type, 1);
00149 }
00150 else
00151 {
00152
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)
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
00213 {
00214 while (!msg->end())
00215 {
00216
00217 ACE_Byte type = *msg->rd_ptr();
00218 ACE_UINT16 vendorId;
00219 ACE_UINT16 vendorType;
00220 if (type == 254)
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)
00228 tList.push_back(EapType(vendorId, vendorType));
00229 }
00230 else
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
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)
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
00272 {
00273 EapTypeList::iterator i;
00274 ACE_UINT32 vendorId, vendorType;
00275
00276
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
00284 for (i=tList.begin(); i!=tList.end(); i++)
00285 {
00286 EapType t = *i;
00287
00288
00289
00290 if (t.type!=254)
00291 t = EapType(0, t.type);
00292
00293
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
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
00345 EapResponseParser responseParser;
00346 responseParser.setRawData(msg);
00347 responseParser.setAppData(identity);
00348 responseParser.parseAppToRaw();
00349
00350
00351 std::string &str = identity->Identity();
00352
00353 UTF8Checker check;
00354
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
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
00409 EapResponseParser responseParser;
00410 responseParser.setRawData(msg);
00411 responseParser.setAppData(notification);
00412 responseParser.parseAppToRaw();
00413
00414
00415
00416 std::string &str = notification->Notification();
00417 UTF8Checker check;
00418
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
00448 ACE_Byte valueSize = (ACE_Byte)*msg->rd_ptr();
00449
00450 msg->rd_ptr(1);
00451
00452
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
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
00482 EapResponseParser responseParser;
00483 responseParser.setRawData(msg);
00484 responseParser.setAppData(md5Challenge);
00485 responseParser.parseAppToRaw();
00486
00487
00488
00489 ACE_Byte valueSize = md5Challenge->Value().size();
00490
00491
00492 if (valueSize == 0)
00493 {
00494 EAP_LOG(LM_ERROR, "Empty value.");
00495 throw -1;
00496 }
00497
00498
00499 msg->copy((const char*)&valueSize, sizeof(valueSize));
00500
00501
00502 msg->copy(md5Challenge->Value().data(), valueSize);
00503
00504
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__