Navigation


Changeset 1300:3f1e79e1273e in freeDiameter


Ignore:
Timestamp:
Aug 30, 2015, 2:11:55 AM (9 years ago)
Author:
Sebastien Decugis <sdecugis@freediameter.net>
Branch:
default
Phase:
public
Message:

Added new callbacks in the derived types definitions to improve value checks during message parsing. Thanks Ranjith for the suggestion.

Files:
4 edited

Legend:

Unmodified
Added
Removed
  • include/freeDiameter/libfdproto.h

    r1295 r1300  
    12591259typedef int (*dict_avpdata_encode) (void * data, union avp_value * val);
    12601260
     1261/*
     1262 * CALLBACK:    dict_avpdata_check
     1263 *
     1264 * PARAMETERS:
     1265 *   val        : Pointer to the AVP value that was received and needs to be sanity checked.
     1266 *   data      : a parameter stored in the type structure (to enable more generic check functions)
     1267 *   error_msg: upon erroneous value, a string describing the error can be returned here (it will be strcpy by caller). This description will be returned in the error message, if any.
     1268 *
     1269 * DESCRIPTION:
     1270 *   This callback can be provided with a derived type in order to improve the operation of the
     1271 *  fd_msg_parse_dict function. When this callback is present, the value of the AVP that has
     1272 * been parsed is passed to this function for finer granularity check. For example for some
     1273 * speccific AVP, the format of an OCTETSTRING value can be further checked, or the
     1274 * interger value can be verified.
     1275 *
     1276 * RETURN VALUE:
     1277 *  0           : The value is valid.
     1278 *  !0          : An error occurred, the error code is returned. It is advised to return EINVAL on incorrect val
     1279 */
     1280typedef int (*dict_avpdata_check) (void * data, union avp_value * val, char ** error_msg);
     1281
     1282
    12611283
    12621284/* Type to hold data associated to a derived AVP data type */
     
    12671289        dict_avpdata_encode      type_encode;   /* cb to convert formatted data into an AVP value (or NULL) */
    12681290        DECLARE_FD_DUMP_PROTOTYPE((*type_dump), union avp_value * val); /* cb called by fd_msg_dump_* for this type of data (if != NULL). Returned string must be freed.  */
     1291        dict_avpdata_check       type_check;
     1292        void  *                          type_check_param;
    12691293};
    12701294
     
    12931317DECLARE_FD_DUMP_PROTOTYPE(fd_dictfct_Time_dump, union avp_value * avp_value);
    12941318
     1319
     1320/* For string AVP, the following type_check function provides simple basic check for specific characters presence, e.g. use "@." for trivial email address check */
     1321int fd_dictfct_CharInOS_check(void * data, union avp_value * val, char ** error_msg);
    12951322
    12961323
  • libfdproto/dictionary_functions.c

    r1284 r1300  
    359359}
    360360
     361/* Check that a given AVP value contains all the characters from data in the same order */
     362static char error_message[80];
     363int fd_dictfct_CharInOS_check(void * data, union avp_value * val, char ** error_msg)
     364{
     365        char * inChar = data;
     366        char * inData = (char *)val->os.data;
     367        int i = 0;
     368        CHECK_PARAMS(data);
     369        while (*inChar != '\0') {
     370                while (i < val->os.len) {
     371                        if (*inChar == inData[i++]) {
     372                                inChar++;
     373                                break;
     374                        }
     375                }
     376                if (i >= val->os.len)
     377                        break;
     378        }
     379        if (*inChar == '\0')
     380                return 0;
     381       
     382        if (error_msg) {
     383                snprintf(error_message, sizeof(error_message), "Could not find '%c' in AVP", *inChar);
     384                *error_msg = error_message;
     385        }
     386        return EBADMSG;
     387}
  • libfdproto/messages.c

    r1298 r1300  
    20372037{
    20382038        struct dict_avp_data dictdata;
     2039        struct dict_type_data derivedtypedata;
     2040        struct dict_object * avp_derived_type = NULL;
    20392041        uint8_t * source;
    20402042       
     
    22172219                        break;
    22182220       
     2221        }
     2222       
     2223        /* Is there a derived type check function ? */
     2224        CHECK_FCT ( fd_dict_search ( dict, DICT_TYPE, TYPE_OF_AVP, avp->avp_model, &avp_derived_type, 0) );
     2225        if (avp_derived_type) {
     2226                CHECK_FCT(  fd_dict_getval(avp_derived_type, &derivedtypedata)  );
     2227                if (derivedtypedata.type_check != NULL) {
     2228                        char * err;
     2229                        int ret = (*derivedtypedata.type_check)( derivedtypedata.type_check_param, &avp->avp_storage, &err );
     2230
     2231                        if (ret != 0) {
     2232                                TRACE_DEBUG(INFO, "The AVP failed to pass the dictionary validation");
     2233                                if (error_info) {                               
     2234                                                error_info->pei_errcode = "DIAMETER_INVALID_AVP_VALUE";
     2235                                                error_info->pei_avp = avp;
     2236                                                strncpy(error_message, err, sizeof(error_message));
     2237                                                error_info->pei_message = error_message;
     2238                                } else {
     2239                                        char * buf = NULL;
     2240                                        size_t buflen;
     2241                                        CHECK_MALLOC(fd_msg_dump_treeview(&buf, &buflen, NULL, avp, NULL, 0, 0));
     2242                                        LOG_E("Invalid AVP: %s", buf);
     2243                                        free(buf);
     2244                                }
     2245                                return ret; /* should we just return EBADMSG? */
     2246                        }
     2247                }
    22192248        }
    22202249       
  • tests/testmesg.c

    r1281 r1300  
    309309                        #endif
    310310                }
     311
     312                {
     313                        struct dict_object  * type = NULL;
     314                        struct dict_type_data type_data = { AVP_TYPE_OCTETSTRING, "OS test2", NULL, NULL, NULL, fd_dictfct_CharInOS_check, "@." };
     315                        struct dict_avp_data  avp_data = { 73575, 73565, "AVP Test - os2", AVP_FLAG_VENDOR, AVP_FLAG_VENDOR, AVP_TYPE_OCTETSTRING };
     316                        CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_TYPE, &type_data , NULL, &type ) );
     317                        CHECK( 0, fd_dict_new ( fd_g_config->cnf_dict, DICT_AVP, &avp_data , type, NULL ) );
     318                }
     319               
    311320                #if 0
    312321                {
     
    753762                                /* reset */
    754763                                CHECK( 0, fd_msg_free ( msg ) );
     764                        }
     765                       
     766                        /* Test with a type verifier */
     767                        {
     768                                struct fd_pei error_info;
     769                                CPYBUF();
     770                                buf_cpy[103] = 0x67;    /* Replaced AVP code = 0x00011F67, OS test2 type in the dictionary */
     771                               
     772                                /* Check that we cannot support this message now */
     773                                CHECK( 0, fd_msg_parse_buffer( &buf_cpy, 344, &msg) );
     774                                CHECK( EBADMSG, fd_msg_parse_dict( msg, fd_g_config->cnf_dict, NULL ) );
     775                               
     776                                /* reset */
     777                                CHECK( 0, fd_msg_free ( msg ) );
     778
     779                                CPYBUF();
     780                                buf_cpy[103] = 0x67;    /* Replaced AVP code = 0x00011F67, OS test2 type in the dictionary */
     781                               
     782                                /* Check error reporting works */
     783                                CHECK( 0, fd_msg_parse_buffer( &buf_cpy, 344, &msg) );
     784                                CHECK( EBADMSG, fd_msg_parse_dict( msg, fd_g_config->cnf_dict, &error_info ) );
     785                               
     786                                #if 1
     787                                fd_log_debug("Error reported: %s\n in AVP: %s", error_info.pei_message, fd_msg_dump_treeview(FD_DUMP_TEST_PARAMS, error_info.pei_avp, fd_g_config->cnf_dict, 0, 1));
     788                                #endif
     789                               
     790                                /* reset */
     791                                CHECK( 0, fd_msg_free ( msg ) );
     792                               
     793                                CPYBUF();
     794                                buf_cpy[103] = 0x67;    /* Replaced AVP code = 0x00011F67, OS test2 type in the dictionary */
     795                                buf_cpy[130] = '@';
     796                                buf_cpy[140] = '.';     /* now we comply to the constraints */
     797                               
     798                                /* Check that we cannot support this message now */
     799                                CHECK( 0, fd_msg_parse_buffer( &buf_cpy, 344, &msg) );
     800                                CHECK( 0, fd_msg_parse_dict( msg, fd_g_config->cnf_dict, NULL ) );
     801                               
     802                                /* reset */
     803                                CHECK( 0, fd_msg_free ( msg ) );
     804                               
     805                               
    755806                        }
    756807                       
     
    13991450        }
    14001451       
    1401 
    14021452        /* That's all for the tests yet */
    14031453        PASSTEST();
Note: See TracChangeset for help on using the changeset viewer.