📄 avpair.c
字号:
/* * $Id: avpair.c,v 1.1 2004/11/14 07:26:26 paulus Exp $ * * Copyright (C) 1995 Lars Fenneberg * * Copyright 1992 Livingston Enterprises, Inc. * * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan * and Merit Network, Inc. All Rights Reserved * * See the file COPYRIGHT for the respective terms and conditions. * If the file is missing contact me at lf@elemental.net * and I'll send you a copy. * */#include <includes.h>#include <radiusclient.h>static void rc_extract_vendor_specific_attributes(int attrlen, unsigned char *ptr, VALUE_PAIR **vp);/* * Function: rc_avpair_add * * Purpose: add an attribute-value pair to the given list. * * Returns: pointer to added a/v pair upon success, NULL pointer upon failure. * * Remarks: Always appends the new pair to the end of the list. * */VALUE_PAIR *rc_avpair_add (VALUE_PAIR **list, int attrid, void *pval, int len, int vendorcode){ VALUE_PAIR *vp; vp = rc_avpair_new (attrid, pval, len, vendorcode); if (vp != (VALUE_PAIR *) NULL) { rc_avpair_insert (list, (VALUE_PAIR *) NULL, vp); } return vp;}/* * Function: rc_avpair_assign * * Purpose: assign the given value to an attribute-value pair. * * Returns: 0 on success, * -1 on failure. * */int rc_avpair_assign (VALUE_PAIR *vp, void *pval, int len){ int result = -1; switch (vp->type) { case PW_TYPE_STRING: if (((len == 0) && (strlen ((char *) pval)) > AUTH_STRING_LEN) || (len > AUTH_STRING_LEN)) { error("rc_avpair_assign: bad attribute length"); return result; } if (len > 0) { memcpy(vp->strvalue, (char *)pval, len); vp->strvalue[len] = '\0'; vp->lvalue = len; } else { strncpy (vp->strvalue, (char *) pval, AUTH_STRING_LEN); vp->lvalue = strlen((char *) pval); } result = 0; break; case PW_TYPE_DATE: case PW_TYPE_INTEGER: case PW_TYPE_IPADDR: vp->lvalue = * (UINT4 *) pval; result = 0; break; default: error("rc_avpair_assign: unknown attribute %d", vp->type); } return result;}/* * Function: rc_avpair_new * * Purpose: make a new attribute-value pair with given parameters. * * Returns: pointer to generated a/v pair when successful, NULL when failure. * */VALUE_PAIR *rc_avpair_new (int attrid, void *pval, int len, int vendorcode){ VALUE_PAIR *vp = (VALUE_PAIR *) NULL; DICT_ATTR *pda; if ((pda = rc_dict_getattr (attrid, vendorcode)) == (DICT_ATTR *) NULL) { error("rc_avpair_new: unknown attribute %d", attrid); } else { if ((vp = (VALUE_PAIR *) malloc (sizeof (VALUE_PAIR))) != (VALUE_PAIR *) NULL) { strncpy (vp->name, pda->name, sizeof (vp->name)); vp->attribute = attrid; vp->vendorcode = vendorcode; vp->next = (VALUE_PAIR *) NULL; vp->type = pda->type; if (rc_avpair_assign (vp, pval, len) == 0) { return vp; } free (vp); vp = (VALUE_PAIR *) NULL; } else novm("rc_avpair_new"); } return vp;}/* * * Function: rc_avpair_gen * * Purpose: takes attribute/value pairs from buffer and builds a * value_pair list using allocated memory. * * Returns: value_pair list or NULL on failure */VALUE_PAIR *rc_avpair_gen (AUTH_HDR *auth){ int length; int x_len; int attribute; int attrlen; UINT4 lvalue; unsigned char *x_ptr; unsigned char *ptr; DICT_ATTR *attr; VALUE_PAIR *vp; VALUE_PAIR *pair; unsigned char hex[3]; /* For hex string conversion. */ char buffer[512]; /* * Extract attribute-value pairs */ ptr = auth->data; length = ntohs ((unsigned short) auth->length) - AUTH_HDR_LEN; vp = (VALUE_PAIR *) NULL; while (length > 0) { attribute = *ptr++; attrlen = *ptr++; attrlen -= 2; if (attrlen < 0) { error("rc_avpair_gen: received attribute with invalid length"); break; } /* Handle vendor-specific specially */ if (attribute == PW_VENDOR_SPECIFIC) { rc_extract_vendor_specific_attributes(attrlen, ptr, &vp); ptr += attrlen; length -= (attrlen + 2); continue; } if ((attr = rc_dict_getattr (attribute, VENDOR_NONE)) == (DICT_ATTR *) NULL) { *buffer= '\0'; /* Initial length. */ for (x_ptr = ptr, x_len = attrlen ; x_len > 0 ; x_len--, x_ptr++) { sprintf (hex, "%2.2X", *x_ptr); strcat (buffer, hex); } warn("rc_avpair_gen: received unknown attribute %d of length %d: 0x%s", attribute, attrlen, buffer); } else { if ((pair = (VALUE_PAIR *) malloc (sizeof (VALUE_PAIR))) == (VALUE_PAIR *) NULL) { novm("rc_avpair_gen"); rc_avpair_free(vp); return NULL; } strcpy (pair->name, attr->name); pair->attribute = attr->value; pair->vendorcode = VENDOR_NONE; pair->type = attr->type; pair->next = (VALUE_PAIR *) NULL; switch (attr->type) { case PW_TYPE_STRING: memcpy (pair->strvalue, (char *) ptr, (size_t) attrlen); pair->strvalue[attrlen] = '\0'; pair->lvalue = attrlen; rc_avpair_insert (&vp, (VALUE_PAIR *) NULL, pair); break; case PW_TYPE_INTEGER: case PW_TYPE_IPADDR: memcpy ((char *) &lvalue, (char *) ptr, sizeof (UINT4)); pair->lvalue = ntohl (lvalue); rc_avpair_insert (&vp, (VALUE_PAIR *) NULL, pair); break; default: warn("rc_avpair_gen: %s has unknown type", attr->name); free (pair); break; } } ptr += attrlen; length -= attrlen + 2; } return (vp);}/* * Function: rc_extract_vendor_specific_attributes * * Purpose: Extracts vendor-specific attributes, assuming they are in * the "SHOULD" format recommended by RCF 2138. * * Returns: found value_pair * */static void rc_extract_vendor_specific_attributes(int attrlen, unsigned char *ptr, VALUE_PAIR **vp){ int vendor_id; int vtype; int vlen; UINT4 lvalue; DICT_ATTR *attr; VALUE_PAIR *pair; /* ptr is sitting at vendor-ID */ if (attrlen < 8) { /* Nothing to see here... */ return; } /* High-order octet of Vendor-Id must be zero (RFC2138) */ if (*ptr) { return; } /* Extract vendor_id */ vendor_id = (int) ( ((unsigned int) ptr[1]) * 256 * 256 + ((unsigned int) ptr[2]) * 256 + ((unsigned int) ptr[3])); /* Bump ptr up to contents */ ptr += 4; /* Set attrlen to length of data */ attrlen -= 4; for (; attrlen; attrlen -= vlen+2, ptr += vlen) { vtype = *ptr++; vlen = *ptr++; vlen -= 2; if (vlen < 0 || vlen > attrlen - 2) { /* Do not log an error. We are supposed to be able to cope with arbitrary vendor-specific gunk */ return; } /* Looks plausible... */ if ((attr = rc_dict_getattr(vtype, vendor_id)) == NULL) { continue; } /* TODO: Check that length matches data size!!!!! */ pair = (VALUE_PAIR *) malloc(sizeof(VALUE_PAIR)); if (!pair) { novm("rc_avpair_gen"); return; } strcpy(pair->name, attr->name); pair->attribute = attr->value; pair->vendorcode = vendor_id; pair->type = attr->type; pair->next = NULL; switch (attr->type) { case PW_TYPE_STRING: memcpy (pair->strvalue, (char *) ptr, (size_t) vlen); pair->strvalue[vlen] = '\0'; pair->lvalue = vlen; rc_avpair_insert (vp, (VALUE_PAIR *) NULL, pair); break; case PW_TYPE_INTEGER: case PW_TYPE_IPADDR: memcpy ((char *) &lvalue, (char *) ptr, sizeof (UINT4)); pair->lvalue = ntohl (lvalue); rc_avpair_insert (vp, (VALUE_PAIR *) NULL, pair); break; default: warn("rc_avpair_gen: %s has unknown type", attr->name); free (pair); break; } }}/* * Function: rc_avpair_get * * Purpose: Find the first attribute value-pair (which matches the given * attribute) from the specified value-pair list. * * Returns: found value_pair * */VALUE_PAIR *rc_avpair_get (VALUE_PAIR *vp, UINT4 attr){ for (; vp != (VALUE_PAIR *) NULL && vp->attribute != attr; vp = vp->next) { continue; } return (vp);}/* * Function: rc_avpair_copy * * Purpose: Return a copy of the existing list "p" ala strdup(). * */VALUE_PAIR *rc_avpair_copy(VALUE_PAIR *p){ VALUE_PAIR *vp, *fp = NULL, *lp = NULL; while (p) { vp = malloc(sizeof(VALUE_PAIR)); if (!vp) { novm("rc_avpair_copy"); return NULL; /* leaks a little but so what */ } *vp = *p; if (!fp) fp = vp; if (lp) lp->next = vp; lp = vp; p = p->next; } return fp;}/* * Function: rc_avpair_insert * * Purpose: Given the address of an existing list "a" and a pointer * to an entry "p" in that list, add the list "b" to * the "a" list after the "p" entry. If "p" is NULL, add * the list "b" to the end of "a". * */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -