@@ -307,42 +307,77 @@ int unmap_eapsim_basictypes(RADIUS_PACKET *r,
307307 newvp -> vp_length = 1 ;
308308 fr_pair_add (& (r -> vps ), newvp );
309309
310+ /*
311+ * EAP-SIM has a 1 octet of subtype, and 2 octets
312+ * reserved.
313+ */
310314 attr += 3 ;
311315 attrlen -= 3 ;
312316
313- /* now, loop processing each attribute that we find */
314- while (attrlen > 0 ) {
317+ /*
318+ * Loop over each attribute. The format is:
319+ *
320+ * 1 octet of type
321+ * 1 octet of length (value 1..255)
322+ * ((4 * length) - 2) octets of data.
323+ */
324+ while (attrlen > 0 ) {
315325 uint8_t * p ;
316326
317- if (attrlen < 2 ) {
327+ if (attrlen < 2 ) {
318328 fr_strerror_printf ("EAP-Sim attribute %d too short: %d < 2" , es_attribute_count , attrlen );
319329 return 0 ;
320330 }
321331
332+ if (!attr [1 ]) {
333+ fr_strerror_printf ("EAP-Sim attribute %d (no.%d) has no data" , eapsim_attribute ,
334+ es_attribute_count );
335+ return 0 ;
336+ }
337+
322338 eapsim_attribute = attr [0 ];
323339 eapsim_len = attr [1 ] * 4 ;
324340
341+ /*
342+ * The length includes the 2-byte header.
343+ */
325344 if (eapsim_len > attrlen ) {
326345 fr_strerror_printf ("EAP-Sim attribute %d (no.%d) has length longer than data (%d > %d)" ,
327346 eapsim_attribute , es_attribute_count , eapsim_len , attrlen );
328347 return 0 ;
329348 }
330349
331- if (eapsim_len > MAX_STRING_LEN ) {
332- eapsim_len = MAX_STRING_LEN ;
333- }
334- if (eapsim_len < 2 ) {
335- fr_strerror_printf ("EAP-Sim attribute %d (no.%d) has length too small" , eapsim_attribute ,
336- es_attribute_count );
337- return 0 ;
338- }
350+ newvp = fr_pair_afrom_num (r , eapsim_attribute + PW_EAP_SIM_BASE , 0 );
351+ if (!newvp ) {
352+ /*
353+ * RFC 4186 Section 8.1 says 0..127 are
354+ * "non-skippable". If one such
355+ * attribute is found and we don't
356+ * understand it, the server has to send:
357+ *
358+ * EAP-Request/SIM/Notification packet with an
359+ * (AT_NOTIFICATION code, which implies general failure ("General
360+ * failure after authentication" (0), or "General failure" (16384),
361+ * depending on the phase of the exchange), which terminates the
362+ * authentication exchange.
363+ */
364+ if (eapsim_attribute <= 127 ) {
365+ fr_strerror_printf ("Unknown mandatory attribute %d, failing" ,
366+ eapsim_attribute );
367+ return 0 ;
368+ }
339369
340- newvp = fr_pair_afrom_num (r , eapsim_attribute + PW_EAP_SIM_BASE , 0 );
341- newvp -> vp_length = eapsim_len - 2 ;
342- newvp -> vp_octets = p = talloc_array (newvp , uint8_t , newvp -> vp_length );
343- memcpy (p , & attr [2 ], eapsim_len - 2 );
344- fr_pair_add (& (r -> vps ), newvp );
345- newvp = NULL ;
370+ } else {
371+ /*
372+ * It's known, ccount for header, and
373+ * copy the value over.
374+ */
375+ newvp -> vp_length = eapsim_len - 2 ;
376+
377+ newvp -> vp_octets = p = talloc_array (newvp , uint8_t , newvp -> vp_length );
378+ memcpy (p , & attr [2 ], newvp -> vp_length );
379+ fr_pair_add (& (r -> vps ), newvp );
380+ }
346381
347382 /* advance pointers, decrement length */
348383 attr += eapsim_len ;
0 commit comments