?? radius_pdu.c
字號:
*/ switch (pdu->type) { #define INTEGER(name, octets) \ append_encoded_integer(os, p->name, octets); #define OCTETS(name, field_giving_octets) \ octstr_append(os, p->name); #define PDU(name, id, fields) \ case id: { struct name *p = &pdu->u.name; fields; oos = radius_attr_pack(pdu); \ octstr_append(os, oos);octstr_destroy(oos); } break; #include "radius_pdu.def" default: error(0, "Unknown RADIUS_PDU type, internal error while packing."); } /* now set PDU length */ temp = octstr_create(""); append_encoded_integer(temp, octstr_len(os), 2); octstr_delete(os, 2, 2); octstr_insert(os, temp, 2); octstr_destroy(temp); return os;}static Octstr *radius_type_convert(int type, Octstr *value){ Octstr *ret = NULL; int i; switch (type) { case t_int: ret = octstr_format("%ld", decode_integer(value, 0, 4)); break; case t_string: ret = octstr_format("%s", octstr_get_cstr(value)); break; case t_ipaddr: ret = octstr_create(""); for (i = 0; i < 4; i++) { int c = octstr_get_char(value, i); Octstr *b = octstr_format("%d", c); octstr_append(ret, b); i < 3 ? octstr_append_cstr(ret, ".") : NULL; octstr_destroy(b); } break; default: panic(0, "RADIUS: Attribute type %d does not exist.", type); break; } return ret;}static void radius_attr_unpack(ParseContext **context, RADIUS_PDU **pdu) { #define ATTR(atype, type, string, pmin, pmax) \ if (atype == attr_type) { \ Octstr *tmp, *value; \ if ((attr_len-2) < pmin || (attr_len-2) > pmax) { \ error(0, "RADIUS: Attribute (%d) `%s' has invalid len %d, droppped.", \ attr_type, string, (attr_len-2)); \ continue; \ } \ attr_val = parse_get_octets(*context, attr_len - 2); \ tmp = octstr_format("RADIUS: Attribute (%d) `%s', len %d", \ attr_type, string, attr_len - 2); \ value = radius_type_convert(type, attr_val); \ octstr_destroy(attr_val); \ octstr_dump_short(value, 0, octstr_get_cstr(tmp)); \ octstr_destroy(tmp); \ attr_str = octstr_create(string); \ dict_put((*pdu)->attr, attr_str, value); \ octstr_destroy(attr_str); \ value = NULL; \ } else #define UNASSIGNED(attr) \ if (attr == attr_type) { \ error(0, "RADIUS: Attribute (%d) is unassigned and should not be used.", \ attr_type); \ continue; \ } else #define ATTRIBUTES(fields) \ while (parse_octets_left(*context) > 0 && !parse_error(*context)) { \ int attr_type, attr_len; \ Octstr *attr_val = NULL; \ Octstr *attr_str = NULL; \ attr_type = parse_get_char(*context); \ attr_len = parse_get_char(*context); \ fields \ { \ debug("radius.unpack", 0, "RADIUS: Unknown attribute type (0x%03lx) " \ "len %d in PDU `%s'.", \ (long unsigned int)attr_type, attr_len, (*pdu)->type_name); \ parse_skip(*context, attr_len - 2); \ } \ } #include "radius_attributes.def"}RADIUS_PDU *radius_pdu_unpack(Octstr *data_without_len){ RADIUS_PDU *pdu; int type, ident; long len, pos; ParseContext *context; Octstr *authenticator; len = octstr_len(data_without_len); if (len < 20) { error(0, "RADIUS: PDU was too short (%ld bytes).", octstr_len(data_without_len)); return NULL; } context = parse_context_create(data_without_len); type = parse_get_char(context); ident = parse_get_char(context); pdu = radius_pdu_create(type, NULL); if (pdu == NULL) return NULL; len = decode_integer(data_without_len, 2, 2) - 19; parse_skip(context, 2); debug("radius", 0, "RADIUS: Attributes len is %ld", len); authenticator = parse_get_octets(context, 16); octstr_dump_short(authenticator, 0, "RADIUS: Authenticator (md5) is:"); /* skipping back to context start for macro magic */ parse_context_destroy(context); context = parse_context_create(data_without_len); switch (type) { #define INTEGER(name, octets) \ pos = octstr_len(data_without_len) - parse_octets_left(context); \ p->name = decode_integer(data_without_len, pos, octets); \ parse_skip(context, octets); #define OCTETS(name, field_giving_octets) \ p->name = parse_get_octets(context, field_giving_octets); #define PDU(name, id, fields) \ case id: { struct name *p = &pdu->u.name; fields; \ radius_attr_unpack(&context, &pdu); } break; #include "radius_pdu.def" default: error(0, "Unknown RADIUS_PDU type, internal error while unpacking."); } parse_context_destroy(context); octstr_destroy(authenticator); return pdu;}int radius_authenticate_pdu(RADIUS_PDU *pdu, Octstr **data, Octstr *secret){ int rc = 0; Octstr *stream; Octstr *attributes; Octstr *digest; stream = attributes = digest = NULL; /* first extract attributes from raw data */ if (octstr_len(*data) > 20) attributes = octstr_copy(*data, 20, octstr_len(*data)-20); switch (pdu->type) { case 0x04: /* Accounting-Request, see RFC2866, page 6 */ stream = octstr_copy(*data, 0, 4); octstr_append_cstr(stream, "0000000000000000"); octstr_append(stream, attributes); octstr_append(stream, secret); digest = md5(stream); rc = octstr_compare(pdu->u.Accounting_Request.authenticator, digest) == 0 ? 1 : 0; debug("",0,"XXXX authenticator:"); octstr_dump(pdu->u.Accounting_Request.authenticator, 0); debug("",0,"XXXX re-calc'ed digest:"); octstr_dump(digest, 0); break; case 0x05: /* Accounting-Response, create Response authenticator */ stream = octstr_duplicate(*data); octstr_append(stream, secret); digest = md5(stream); octstr_delete(*data, 4, 16); octstr_insert(*data, digest, 4); break; default: break; } octstr_destroy(attributes); octstr_destroy(stream); octstr_destroy(digest); return rc;}static void radius_attr_dump(RADIUS_PDU *pdu){ #define UNASSIGNED(attr) #define ATTR(atype, type, string, pmin, pmax) \ id = atype; \ key = octstr_create(string); \ val = dict_get(pdu->attr, key); \ if (val != NULL) \ octstr_dump_short(val, 2, #atype); \ octstr_destroy(key); #define ATTRIBUTES(fields) \ if (pdu->attr != NULL) { \ Octstr *key = NULL, *val = NULL; \ int id; \ fields \ } #include "radius_attributes.def"}void radius_pdu_dump(RADIUS_PDU *pdu){ debug("radius", 0, "RADIUS PDU %p dump:", (void *) pdu); debug("radius", 0, " type_name: %s", pdu->type_name); switch (pdu->type) { #define INTEGER(name, octets) \ debug("radius", 0, " %s: %lu = 0x%08lx", #name, p->name, p->name); #define OCTETS(name, field_giving_octets) \ octstr_dump_short(p->name, 2, #name); #define PDU(name, id, fields) \ case id: { struct name *p = &pdu->u.name; fields; \ radius_attr_dump(pdu); } break; #include "radius_pdu.def" default: error(0, "Unknown RADIUS_PDU type, internal error."); break; } debug("radius", 0, "RADIUS PDU dump ends.");}Octstr *radius_get_attribute(RADIUS_PDU *pdu, Octstr *attribute){ gw_assert(pdu != NULL); if (pdu->attr == NULL) return NULL; return dict_get(pdu->attr, attribute);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -