Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
radius_pdu.h File Reference
#include "gwlib/gwlib.h"
#include "gwlib/dict.h"
#include "radius_attributes.def"
#include "radius_pdu.def"

Go to the source code of this file.

Data Structures

struct  RADIUS_PDU
 

Macros

#define ATTR(attr, type, string, min, max)
 
#define UNASSIGNED(attr)
 
#define ATTRIBUTES(fields)
 
#define INTEGER(name, octets)
 
#define OCTETS(name, field_giving_octets)
 
#define PDU(name, id, fields)   name = id,
 
#define ATTR(attr, type, string, min, max)
 
#define UNASSIGNED(attr)
 
#define ATTRIBUTES(fields)
 
#define INTEGER(name, octets)   unsigned long name;
 
#define NULTERMINATED(name, max_octets)   Octstr *name;
 
#define OCTETS(name, field_giving_octets)   Octstr *name;
 
#define PDU(name, id, fields)   struct name { fields } name;
 

Typedefs

typedef struct RADIUS_PDU RADIUS_PDU
 

Enumerations

enum  { t_int, t_string, t_ipaddr }
 
enum  { ATTRIBUTES, ATTRIBUTES }
 

Functions

RADIUS_PDUradius_pdu_create (int type, RADIUS_PDU *req)
 
void radius_pdu_destroy (RADIUS_PDU *pdu)
 
int radius_authenticate_pdu (RADIUS_PDU *pdu, Octstr **data, Octstr *secret)
 
Octstrradius_pdu_pack (RADIUS_PDU *pdu)
 
RADIUS_PDUradius_pdu_unpack (Octstr *data_without_len)
 
void radius_pdu_dump (RADIUS_PDU *pdu)
 
Octstrradius_get_attribute (RADIUS_PDU *pdu, Octstr *attribute)
 

Macro Definition Documentation

#define ATTR (   attr,
  type,
  string,
  min,
  max 
)

Definition at line 95 of file radius_pdu.h.

#define ATTR (   attr,
  type,
  string,
  min,
  max 
)

Definition at line 95 of file radius_pdu.h.

#define ATTRIBUTES (   fields)

Definition at line 97 of file radius_pdu.h.

#define ATTRIBUTES (   fields)

Definition at line 97 of file radius_pdu.h.

#define INTEGER (   name,
  octets 
)
#define INTEGER (   name,
  octets 
)    unsigned long name;
#define NULTERMINATED (   name,
  max_octets 
)    Octstr *name;
#define OCTETS (   name,
  field_giving_octets 
)
#define OCTETS (   name,
  field_giving_octets 
)    Octstr *name;
#define PDU (   name,
  id,
  fields 
)    name = id,
#define PDU (   name,
  id,
  fields 
)    struct name { fields } name;
#define UNASSIGNED (   attr)

Definition at line 96 of file radius_pdu.h.

#define UNASSIGNED (   attr)

Definition at line 96 of file radius_pdu.h.

Typedef Documentation

typedef struct RADIUS_PDU RADIUS_PDU

Definition at line 89 of file radius_pdu.h.

Enumeration Type Documentation

anonymous enum
Enumerator
t_int 
t_string 
t_ipaddr 

Definition at line 72 of file radius_pdu.h.

72  {
74 };
anonymous enum
Enumerator
ATTRIBUTES 
ATTRIBUTES 

Definition at line 76 of file radius_pdu.h.

76  {
77  #define ATTR(attr, type, string, min, max)
78  #define UNASSIGNED(attr)
79  #define ATTRIBUTES(fields)
80  #include "radius_attributes.def"
81  #define INTEGER(name, octets)
82  #define OCTETS(name, field_giving_octets)
83  #define PDU(name, id, fields) name = id,
84  #include "radius_pdu.def"
85  RADIUS_PDU_DUMMY_TYPE
86 };

Function Documentation

int radius_authenticate_pdu ( RADIUS_PDU pdu,
Octstr **  data,
Octstr secret 
)

Definition at line 416 of file radius_pdu.c.

References md5(), octstr_append(), octstr_append_data(), octstr_compare(), octstr_copy, octstr_delete(), octstr_destroy(), octstr_duplicate, octstr_insert(), octstr_len(), RADIUS_PDU::type, and RADIUS_PDU::u.

Referenced by main(), proxy_thread(), and server().

417 {
418  int rc = 0;
419  Octstr *stream;
420  Octstr *attributes;
421  Octstr *digest;
422 
423  stream = attributes = digest = NULL;
424 
425  /* first extract attributes from raw data, where
426  * the first 20 octets are code, idendifier, length
427  * and authenticator value as described in RFC2866, sec. 3 */
428  if (octstr_len(*data) > 20)
429  attributes = octstr_copy(*data, 20, octstr_len(*data)-20);
430 
431  switch (pdu->type) {
432  case 0x04: /* Accounting-Request, see RFC2866, page 6 */
433  stream = octstr_copy(*data, 0, 4);
434  octstr_append_data(stream, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16);
435  octstr_append(stream, attributes);
436  octstr_append(stream, secret);
437  digest = md5(stream);
438  rc = octstr_compare(pdu->u.Accounting_Request.authenticator,
439  digest) == 0 ? 1 : 0;
440  break;
441  case 0x05: /* Accounting-Response, create Response authenticator */
442  stream = octstr_duplicate(*data);
443  octstr_append(stream, secret);
444  digest = md5(stream);
445  octstr_delete(*data, 4, 16);
446  octstr_insert(*data, digest, 4);
447  break;
448  default:
449  break;
450  }
451 
452  octstr_destroy(attributes);
453  octstr_destroy(stream);
454  octstr_destroy(digest);
455 
456  return rc;
457 }
Octstr * md5(Octstr *data)
Definition: md5.c:387
void octstr_append_data(Octstr *ostr, const char *data, long len)
Definition: octstr.c:1495
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1502
union RADIUS_PDU::@72 u
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
Definition: octstr.c:1301
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1525
#define octstr_duplicate(ostr)
Definition: octstr.h:187
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:869
Octstr* radius_get_attribute ( RADIUS_PDU pdu,
Octstr attribute 
)

Definition at line 498 of file radius_pdu.c.

References RADIUS_PDU::attr, dict_get(), and gw_assert().

499 {
500  gw_assert(pdu != NULL);
501 
502  if (pdu->attr == NULL)
503  return NULL;
504 
505  return dict_get(pdu->attr, attribute);
506 }
Dict * attr
Definition: radius_pdu.h:93
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
gw_assert(wtls_machine->packet_to_send!=NULL)
RADIUS_PDU* radius_pdu_create ( int  type,
RADIUS_PDU req 
)

Definition at line 123 of file radius_pdu.c.

References error(), RADIUS_PDU::type, and type.

Referenced by main(), proxy_thread(), radius_pdu_unpack(), and server().

124 {
125  RADIUS_PDU *pdu;
126 
127  pdu = gw_malloc(sizeof(*pdu));
128  pdu->type = type;
129 
130  switch (type) {
131  #define INTEGER(name, octets) \
132  if (strcmp(#name, "code") == 0) p->name = type; \
133  else p->name = 0;
134  #define OCTETS(name, field_giving_octets) p->name = NULL;
135  #define PDU(name, id, fields) \
136  case id: { \
137  struct name *p = &pdu->u.name; \
138  pdu->type_name = #name; \
139  fields \
140  } break;
141  #include "radius_pdu.def"
142  default:
143  error(0, "Unknown RADIUS_PDU type, internal error.");
144  gw_free(pdu);
145  return NULL;
146  }
147  #define ATTR(attr, type, string, min, max)
148  #define UNASSIGNED(attr)
149  #define ATTRIBUTES(fields) \
150  pdu->attr = dict_create(20, (void (*)(void *))octstr_destroy);
151  #include "radius_attributes.def"
152 
153  return pdu;
154 }
void error(int err, const char *fmt,...)
Definition: log.c:612
int type
Definition: smsc_cimd2.c:215
void radius_pdu_destroy ( RADIUS_PDU pdu)

Definition at line 156 of file radius_pdu.c.

References error(), and RADIUS_PDU::type.

Referenced by main(), proxy_thread(), and server().

157 {
158  if (pdu == NULL)
159  return;
160 
161  switch (pdu->type) {
162  #define INTEGER(name, octets) p->name = 0;
163  #define OCTETS(name, field_giving_octets) octstr_destroy(p->name);
164  #define PDU(name, id, fields) \
165  case id: { struct name *p = &pdu->u.name; fields } break;
166  #include "radius_pdu.def"
167  default:
168  error(0, "Unknown RADIUS_PDU type, internal error while destroying.");
169  }
170 
171  #define ATTR(attr, type, string, min, max)
172  #define UNASSIGNED(attr)
173  #define ATTRIBUTES(fields) dict_destroy(pdu->attr);
174  #include "radius_attributes.def"
175 
176  gw_free(pdu);
177 }
void error(int err, const char *fmt,...)
Definition: log.c:612
void radius_pdu_dump ( RADIUS_PDU pdu)

Definition at line 478 of file radius_pdu.c.

References debug(), error(), RADIUS_PDU::type, and RADIUS_PDU::type_name.

479 {
480  debug("radius", 0, "RADIUS PDU %p dump:", (void *) pdu);
481  debug("radius", 0, " type_name: %s", pdu->type_name);
482  switch (pdu->type) {
483  #define INTEGER(name, octets) \
484  debug("radius", 0, " %s: %lu = 0x%08lx", #name, p->name, p->name);
485  #define OCTETS(name, field_giving_octets) \
486  octstr_dump_short(p->name, 2, #name);
487  #define PDU(name, id, fields) \
488  case id: { struct name *p = &pdu->u.name; fields; \
489  radius_attr_dump(pdu); } break;
490  #include "radius_pdu.def"
491  default:
492  error(0, "Unknown RADIUS_PDU type, internal error.");
493  break;
494  }
495  debug("radius", 0, "RADIUS PDU dump ends.");
496 }
void error(int err, const char *fmt,...)
Definition: log.c:612
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
const char * type_name
Definition: radius_pdu.h:92
Octstr* radius_pdu_pack ( RADIUS_PDU pdu)

Definition at line 237 of file radius_pdu.c.

References append_encoded_integer(), error(), gw_assert(), octstr_create, octstr_delete(), octstr_destroy(), octstr_insert(), octstr_len(), and RADIUS_PDU::type.

Referenced by main(), proxy_thread(), and server().

238 {
239  Octstr *os,*oos;
240  Octstr *temp;
241 
242  os = octstr_create("");
243 
244  gw_assert(pdu != NULL);
245 
246  /*
247  switch (pdu->type) {
248  #define INTEGER(name, octets) p = *(&p);
249  #define NULTERMINATED(name, max_octets) p = *(&p);
250  #define OCTETS(name, field_giving_octets) \
251  p->field_giving_octets = octstr_len(p->name);
252  #define PDU(name, id, fields) \
253  case id: { struct name *p = &pdu->u.name; fields } break;
254  #include "radius_pdu.def"
255  default:
256  error(0, "Unknown RADIUS_PDU type, internal error while packing.");
257  }
258  */
259 
260  switch (pdu->type) {
261  #define INTEGER(name, octets) \
262  append_encoded_integer(os, p->name, octets);
263  #define OCTETS(name, field_giving_octets) \
264  octstr_append(os, p->name);
265  #define PDU(name, id, fields) \
266  case id: { struct name *p = &pdu->u.name; fields; oos = radius_attr_pack(pdu); \
267  octstr_append(os, oos);octstr_destroy(oos); } break;
268  #include "radius_pdu.def"
269  default:
270  error(0, "Unknown RADIUS_PDU type, internal error while packing.");
271  }
272 
273  /* now set PDU length */
274  temp = octstr_create("");
275  append_encoded_integer(temp, octstr_len(os), 2);
276  octstr_delete(os, 2, 2);
277  octstr_insert(os, temp, 2);
278  octstr_destroy(temp);
279 
280  return os;
281 }
void error(int err, const char *fmt,...)
Definition: log.c:612
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
Definition: octstr.c:1301
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1525
static void append_encoded_integer(Octstr *os, unsigned long u, long octets)
Definition: radius_pdu.c:91
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
#define octstr_create(cstr)
Definition: octstr.h:125
gw_assert(wtls_machine->packet_to_send!=NULL)
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
RADIUS_PDU* radius_pdu_unpack ( Octstr data_without_len)

Definition at line 360 of file radius_pdu.c.

References debug(), decode_integer(), error(), octstr_destroy(), octstr_dump_short(), octstr_len(), parse_context_create(), parse_context_destroy(), parse_get_char(), parse_get_octets(), parse_skip(), radius_pdu_create(), and type.

Referenced by main(), proxy_thread(), and server().

361 {
362  RADIUS_PDU *pdu;
363  int type;
364  long len, pos;
366  Octstr *authenticator;
367 
368  len = octstr_len(data_without_len);
369 
370  if (len < 20) {
371  error(0, "RADIUS: PDU was too short (%ld bytes).",
372  octstr_len(data_without_len));
373  return NULL;
374  }
375 
376  context = parse_context_create(data_without_len);
377 
378  type = parse_get_char(context);
379  parse_get_char(context);
380  pdu = radius_pdu_create(type, NULL);
381  if (pdu == NULL)
382  return NULL;
383 
384  len = decode_integer(data_without_len, 2, 2) - 19;
385  parse_skip(context, 2);
386  debug("radius", 0, "RADIUS: Attributes len is %ld", len);
387 
388  authenticator = parse_get_octets(context, 16);
389  octstr_dump_short(authenticator, 0, "RADIUS: Authenticator (md5) is:");
390 
391  /* skipping back to context start for macro magic */
392  parse_context_destroy(context);
393  context = parse_context_create(data_without_len);
394 
395  switch (type) {
396  #define INTEGER(name, octets) \
397  pos = octstr_len(data_without_len) - parse_octets_left(context); \
398  p->name = decode_integer(data_without_len, pos, octets); \
399  parse_skip(context, octets);
400  #define OCTETS(name, field_giving_octets) \
401  p->name = parse_get_octets(context, field_giving_octets);
402  #define PDU(name, id, fields) \
403  case id: { struct name *p = &pdu->u.name; fields; \
404  radius_attr_unpack(&context, &pdu); } break;
405  #include "radius_pdu.def"
406  default:
407  error(0, "Unknown RADIUS_PDU type, internal error while unpacking.");
408  }
409 
410  parse_context_destroy(context);
411  octstr_destroy(authenticator);
412 
413  return pdu;
414 }
void error(int err, const char *fmt,...)
Definition: log.c:612
int parse_get_char(ParseContext *context)
Definition: parse.c:218
Definition: parse.c:65
int type
Definition: smsc_cimd2.c:215
void octstr_dump_short(Octstr *ostr, int level, const char *name)
Definition: octstr.c:2142
Octstr * parse_get_octets(ParseContext *context, long length)
Definition: parse.c:230
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
int parse_skip(ParseContext *context, long count)
Definition: parse.c:166
void parse_context_destroy(ParseContext *context)
Definition: parse.c:88
RADIUS_PDU * radius_pdu_create(int type, RADIUS_PDU *req)
Definition: radius_pdu.c:123
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:690
static unsigned long decode_integer(Octstr *os, long pos, int octets)
Definition: radius_pdu.c:76
ParseContext * parse_context_create(Octstr *str)
Definition: parse.c:74
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.