Navigation


Changeset 706:4ffbc9f1e922 in freeDiameter for extensions/app_radgw


Ignore:
Timestamp:
Feb 9, 2011, 3:26:58 PM (13 years ago)
Author:
Sebastien Decugis <sdecugis@nict.go.jp>
Branch:
default
Phase:
public
Message:

Large UNTESTED commit with the following changes:

  • Improved DiameterIdentity? handling (esp. interationalization issues), and improve efficiency of some string operations in peers, sessions, and dictionary modules (closes #7)
  • Cleanup in the session module to free only unreferenced sessions (#16)
  • Removed fd_cpu_flush_cache(), replaced by more robust alternatives.
  • Improved peer state machine algorithm to counter SCTP multistream race condition.
Location:
extensions/app_radgw
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • extensions/app_radgw/rgw_clients.c

    r554 r706  
    8686        int                      is_local; /* true if the RADIUS client runs on the same host -- we use Diameter Identity in that case */
    8787        enum rgw_cli_type        type; /* is it a proxy ? */
    88         char                    *fqdn;
     88        DiamId_t                 fqdn; /* malloc'd here */
    8989        size_t                   fqdn_len;
    90         char                    *realm;
    91         char                    **aliases;
     90        DiamId_t                 realm; /* references another string, do not free */
     91        size_t                   realm_len;
     92        struct {
     93                os0_t            name;
     94                size_t           len;
     95        }                       *aliases; /* Received aliases */
    9296        size_t                   aliases_nb;
    9397       
     
    210214{
    211215        struct rgw_client *tmp = NULL;
    212         char buf[255];
     216        DiamId_t fqdn;
     217        size_t fqdn_len;
    213218        int ret, i;
    214219        int loc = 0;
     
    220225                loc = 1;
    221226        } else {
     227                char buf[255];
    222228       
    223229                /* Search FQDN for the client */
     
    227233                        return EINVAL;
    228234                }
     235                fqdn = &buf[0];
     236                CHECK_FCT_DO( ret = fd_os_validate_DiameterIdentity(&fqdn, &fqdn_len, 1),
     237                        {
     238                                TRACE_DEBUG(INFO, "Unable to use resolved peer name '%s' as DiameterIdentity: %s", buf, strerror(ret));
     239                                return ret;
     240                        } );
    229241        }
    230242       
     
    246258        } else {
    247259                /* Copy the fqdn */
    248                 CHECK_MALLOC( tmp->fqdn = strdup(buf) );
    249                 tmp->fqdn_len = strlen(tmp->fqdn);
     260                tmp->fqdn = fqdn;
     261                tmp->fqdn_len = fqdn_len;
     262
    250263                /* Find an appropriate realm */
    251                 tmp->realm = strchr(tmp->fqdn, '.');
    252                 if (tmp->realm)
     264                tmp->realm = strchr(fqdn, '.');
     265                if (tmp->realm) {
    253266                        tmp->realm += 1;
    254                 if ((!tmp->realm) || (*tmp->realm == '\0')) /* in case the fqdn was "localhost." for example, if it is possible... */
     267                        tmp->realm_len = tmp->fqdn_len - (tmp->realm - fqdn);
     268                }
     269                if ((!tmp->realm) || (*tmp->realm == '\0')) { /* in case the fqdn was "localhost." for example, if it is possible... */
    255270                        tmp->realm = fd_g_config->cnf_diamrlm;
     271                        tmp->realm_len = fd_g_config->cnf_diamrlm_len;
     272                }
    256273        }
    257274       
     
    282299                /* Free the data */
    283300                for (idx = 0; idx < client->aliases_nb; idx++)
    284                         free(client->aliases[idx]);
     301                        free(client->aliases[idx].name);
    285302                free(client->aliases);
    286303                free(client->fqdn);
     
    532549        int valid_nas_info = 0;
    533550        struct radius_attr_hdr *nas_ip = NULL, *nas_ip6 = NULL, *nas_id = NULL;
    534         char * oh_str = NULL;
    535         char * or_str = NULL;
    536         char * rr_str = NULL;
     551        size_t nas_id_len;
     552        char * oh_str = NULL; size_t oh_strlen; int oh_free = 0;
     553        char * or_str = NULL; size_t or_strlen;
     554        char * rr_str = NULL; size_t rr_strlen;
    537555        char buf[REVERSE_DNS_SIZE_MAX]; /* to store DNS lookups results */
    538556       
     
    555573                if ((attr->type == RADIUS_ATTR_NAS_IDENTIFIER) && (attr_len > 0)) {
    556574                        nas_id = attr;
     575                        nas_id_len = attr_len;
    557576                        continue;
    558577                }
     
    568587               
    569588                /* Get information on this peer */
    570                 CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &or_str) );
     589                CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &oh_strlen, &or_str, &or_strlen) );
    571590               
    572591                goto diameter;
     
    619638                                return EINVAL;
    620639                        } else {
     640                                int ret;
     641                                sSS ss;
    621642                                /* the peer is configured as a proxy, or running on localhost, so accept the message */
    622                                 sSS ss;
    623643                               
    624644                                /* In that case, the cli will be stored as Route-Record and the NAS-IP-Address as origin */
    625645                                if (!cli->is_local) {
    626646                                        rr_str = cli->fqdn;
     647                                        rr_strlen = cli->fqdn_len;
    627648                                }
    628649                               
     
    641662                                        {
    642663                                                if (cli->is_local) {
    643                                                         CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &or_str) );
     664                                                        CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &oh_strlen, &or_str, &or_strlen) );
    644665                                                        goto diameter;
    645666                                                }
     
    648669                                                return EINVAL;
    649670                                        } );
     671                                       
     672                                oh_str = &buf[0];
     673                                CHECK_FCT_DO( ret = fd_os_validate_DiameterIdentity(&oh_str, &oh_strlen, 1),
     674                                        {
     675                                                if (cli->is_local) {
     676                                                        CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &oh_strlen, &or_str, &or_strlen) );
     677                                                        goto diameter;
     678                                                }
     679                                               
     680                                                TRACE_DEBUG(INFO, "Unable to use resolved client name '%s' as DiameterIdentity: %s", buf, strerror(ret));
     681                                                return ret;
     682                                        } );
     683                                oh_free = 1;
    650684                               
    651                                 oh_str = &buf[0];
    652685                                or_str = strchr(oh_str, '.');
    653686                                if (or_str) {
     
    655688                                        if (*or_str == '\0')
    656689                                                or_str = NULL; /* Discard this realm, we will use the local realm later */
     690                                        else
     691                                                or_strlen = oh_strlen - (or_str - oh_str);
    657692                                }
    658693                        }
    659694                } else {
    660695                        /* The attribute matches the source address, just use this in origin-host */
    661                         CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &or_str) );
     696                        CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &oh_strlen, &or_str, &or_strlen) );
    662697                }
    663698               
     
    668703        if (cli->is_local) {
    669704                /* Simple: we use our own configuration */
    670                 CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &or_str) );
     705                CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &oh_strlen, &or_str, &or_strlen) );
    671706                goto diameter;
    672707        }
     
    697732               
    698733                /* first, check if the nas_id is the fqdn of the peer or a known alias */
    699                 if ((cli->fqdn_len == (nas_id->length - sizeof(struct radius_attr_hdr)))
    700                 && (!strncasecmp((char *)(nas_id + 1), cli->fqdn, nas_id->length - sizeof(struct radius_attr_hdr)))) {
     734                if (!fd_os_almostcasecmp(nas_id + 1, nas_id_len,
     735                                                cli->fqdn, cli->fqdn_len)) {
    701736                        TRACE_DEBUG(FULL, "NAS-Identifier contains the fqdn of the client");
    702737                        found = 1;
    703738                } else {
    704739                        for (idx = 0; idx < cli->aliases_nb; idx++) {
    705                                 if (((nas_id->length - sizeof(struct radius_attr_hdr)) == strlen(cli->aliases[idx]))
    706                                 && (!strncasecmp((char *)(nas_id + 1), cli->aliases[idx], nas_id->length - sizeof(struct radius_attr_hdr)))) {
     740                                if (!fd_os_cmp(nas_id + 1, nas_id_len,
     741                                                cli->aliases[idx].name, cli->aliases[idx].len)) {
    707742                                        TRACE_DEBUG(FULL, "NAS-Identifier valid value found in the cache");
    708743                                        found = 1;
     
    714749                if (found) {
    715750                        /* The NAS-Identifier matches the source IP */
    716                         CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &or_str) );
     751                        CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &oh_strlen, &or_str, &or_strlen) );
    717752
    718753                        goto diameter;
     
    720755               
    721756                /* Attempt DNS resolution of the identifier */
    722                 ASSERT( nas_id->length - sizeof(struct radius_attr_hdr) < sizeof(buf) );
    723                 memcpy(buf, nas_id + 1, nas_id->length - sizeof(struct radius_attr_hdr));
     757                ASSERT( nas_id_len < sizeof(buf) );
     758                memcpy(buf, nas_id + 1, nas_id_len);
    724759                buf[nas_id->length - sizeof(struct radius_attr_hdr)] = '\0';
    725760               
     
    745780                                if (cli->type == RGW_CLI_NAS) {
    746781                                        TRACE_DEBUG(INFO, "The NAS-Identifier value '%.*s' resolves to a different IP than the client's, discarding the message. \nConfigure this client as a Proxy if this message should be valid.",
    747                                                 nas_id->length - sizeof(struct radius_attr_hdr), nas_id + 1);
     782                                                nas_id_len, nas_id + 1);
    748783                                        return EINVAL;
    749784                                } else {
     
    751786                                        if (!cli->is_local) {
    752787                                                rr_str = cli->fqdn;
     788                                                rr_strlen = cli->fqdn_len;
    753789                                        }
    754790                                        oh_str = &buf[0]; /* The canonname resolved */
     791                                        CHECK_FCT_DO( ret = fd_os_validate_DiameterIdentity(&oh_str, &oh_strlen, 1),
     792                                                {
     793                                                        TRACE_DEBUG(INFO, "Unable to use resolved client name '%s' as DiameterIdentity: %s", buf, strerror(ret));
     794                                                        return ret;
     795                                                } );
     796                                        oh_free = 1;
    755797                                        or_str = strchr(oh_str, '.');
    756798                                        if (or_str) {
     
    758800                                                if (*or_str == '\0')
    759801                                                        or_str = NULL; /* Discard this realm, we will use the local realm later */
     802                                                else
     803                                                        or_strlen = oh_strlen - (or_str - oh_str);
    760804                                        }
    761805                                }
    762806                        } else {
    763807                                /* It is a valid alias, save it */
    764                                 CHECK_MALLOC( cli->aliases = realloc(cli->aliases, (cli->aliases_nb + 1) * sizeof(char *)) );
    765                                 CHECK_MALLOC( cli->aliases[cli->aliases_nb + 1] = malloc( 1 + nas_id->length - sizeof(struct radius_attr_hdr) ));
    766                                 memcpy( cli->aliases[cli->aliases_nb + 1], nas_id + 1, nas_id->length - sizeof(struct radius_attr_hdr));
    767                                 *(cli->aliases[cli->aliases_nb + 1] + nas_id->length - sizeof(struct radius_attr_hdr)) = '\0';
     808                                CHECK_MALLOC( cli->aliases = realloc(cli->aliases, (cli->aliases_nb + 1) * sizeof(cli->aliases[0])) );
     809                               
     810                                CHECK_MALLOC( cli->aliases[cli->aliases_nb + 1].name = os0dup(nas_id + 1, nas_id_len ) );
     811                                cli->aliases[cli->aliases_nb + 1].len = nas_id_len;
     812
    768813                                cli->aliases_nb ++;
    769                                 TRACE_DEBUG(FULL, "Saved valid alias for client: '%s' -> '%s'", cli->aliases[cli->aliases_nb + 1], cli->fqdn);
    770                                 CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &or_str) );
     814                                TRACE_DEBUG(FULL, "Saved valid alias for client: '%.*s' -> '%s'", nas_id_len, nas_id + 1, cli->fqdn);
     815                                CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &oh_strlen, &or_str, &or_strlen) );
    771816                        }
    772817                } else {
     
    774819                        TRACE_DEBUG(INFO, "NAS-Identifier '%s' cannot be resolved: %s. Ignoring...", buf, gai_strerror(ret));
    775820                        /* Assume this is a valid identifier for the client */
    776                         CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &or_str) );
     821                        CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &oh_strlen, &or_str, &or_strlen) );
    777822                }
    778823        }
     
    781826diameter:
    782827        ASSERT(oh_str); /* If it is not defined here, there is a bug... */
    783         if (!or_str)
     828        if (!or_str) {
    784829                or_str = fd_g_config->cnf_diamrlm; /* Use local realm in that case */
     830                or_strlen = fd_g_config->cnf_diamrlm_len;
     831        }
    785832       
    786833        /* Create an empty Diameter message so that extensions can store their AVPs */
     
    791838        memset(&avp_val, 0, sizeof(avp_val));
    792839        avp_val.os.data = (unsigned char *)oh_str;
    793         avp_val.os.len = strlen(oh_str);
     840        avp_val.os.len = oh_strlen;
    794841        CHECK_FCT( fd_msg_avp_setvalue ( avp, &avp_val ) );
    795842        CHECK_FCT( fd_msg_avp_add ( *diam, MSG_BRW_LAST_CHILD, avp) );
     
    799846        memset(&avp_val, 0, sizeof(avp_val));
    800847        avp_val.os.data = (unsigned char *)or_str;
    801         avp_val.os.len = strlen(or_str);
     848        avp_val.os.len = or_strlen;
    802849        CHECK_FCT( fd_msg_avp_setvalue ( avp, &avp_val ) );
    803850        CHECK_FCT( fd_msg_avp_add ( *diam, MSG_BRW_LAST_CHILD, avp) );
     
    807854                memset(&avp_val, 0, sizeof(avp_val));
    808855                avp_val.os.data = (unsigned char *)rr_str;
    809                 avp_val.os.len = strlen(rr_str);
     856                avp_val.os.len = rr_strlen;
    810857                CHECK_FCT( fd_msg_avp_setvalue ( avp, &avp_val ) );
    811858                CHECK_FCT( fd_msg_avp_add ( *diam, MSG_BRW_LAST_CHILD, avp) );
    812859        }
    813860       
     861        if (oh_free)
     862                free(oh_str);
     863       
    814864        /* Done! */
    815865        return 0;
    816866}
    817867
    818 int rgw_clients_get_origin(struct rgw_client *cli, char **fqdn, char **realm)
    819 {
    820         TRACE_ENTRY("%p %p %p", cli, fqdn, realm);
    821         CHECK_PARAMS(cli && fqdn);
     868int rgw_clients_get_origin(struct rgw_client *cli, DiamId_t *fqdn, size_t *fqdnlen, DiamId_t *realm, size_t *realmlen)
     869{
     870        TRACE_ENTRY("%p %p %p %p %p", cli, fqdn, fqdnlen, realm, realmlen);
     871        CHECK_PARAMS(cli && fqdn && fqdnlen);
    822872       
    823873        if (cli->is_local) {
    824874                *fqdn = fd_g_config->cnf_diamid;
     875                *fqdnlen = fd_g_config->cnf_diamid_len;
    825876                if (realm)
    826877                        *realm= fd_g_config->cnf_diamrlm;
     878                if (realmlen)
     879                        *realmlen= fd_g_config->cnf_diamrlm_len;
    827880        } else {
    828881                *fqdn = cli->fqdn;
     882                *fqdnlen = cli->fqdn_len;
    829883                if (realm)
    830884                        *realm= cli->realm;
     885                if (realmlen)
     886                        *realmlen= cli->realm_len;
    831887        }
    832888               
  • extensions/app_radgw/rgw_common.h

    r403 r706  
    5959int    rgw_clients_getkey(struct rgw_client * cli, unsigned char **key, size_t *key_len);
    6060char * rgw_clients_id(struct rgw_client *cli);
    61 int    rgw_clients_get_origin(struct rgw_client *cli, char **fqdn, char **realm);
     61int    rgw_clients_get_origin(struct rgw_client *cli, DiamId_t *fqdn, size_t *fqdnlen, DiamId_t *realm, size_t *realmlen);
    6262
    6363/* Each plugin must provide the following structure. */
  • extensions/app_radgw/rgw_servers.c

    r553 r706  
    148148                CHECK_FCT_DO( rgw_msg_parse(&buf[0], len, &msg),
    149149                        {
    150                                 char * cliname = NULL;
    151                                 CHECK_FCT_DO( rgw_clients_get_origin(nas_info, &cliname, NULL), );
     150                                DiamId_t cliname = NULL;
     151                                size_t clisz;
     152                                CHECK_FCT_DO( rgw_clients_get_origin(nas_info, &cliname, &clisz, NULL, NULL), );
    152153                                TRACE_DEBUG(INFO, "Discarding invalid RADIUS message from '%s'", cliname);
    153154                                rgw_clients_dispose(&nas_info);
  • extensions/app_radgw/rgwx_acct.c

    r705 r706  
    306306        const char * prefix = "Diameter/";
    307307        size_t pref_len;
    308         uint8_t * si = NULL;
     308        os0_t si = NULL;
    309309        size_t si_len = 0;
    310         uint8_t * un = NULL;
     310        os0_t un = NULL;
    311311        size_t un_len = 0;
    312312       
     
    487487        /* Create the Session-Id AVP if needed */
    488488        if (!*session) {
    489                 CHECK_FCT( fd_sess_fromsid ( (char *)/* cast should be removed later */si, si_len, session, NULL) );
     489                CHECK_FCT( fd_sess_fromsid ( si, si_len, session, NULL) );
    490490               
    491491                TRACE_DEBUG(FULL, "[acct.rgwx] Translating new accounting message for session '%.*s'...", si_len, si);
     
    663663                                        char * attr_val, *auth_val;
    664664                                        attr_val = (char *)(attr + 1);
    665                                         auth_val = attr_val + strlen(CLASS_AAI_PREFIX);
    666                                         if (    (attr->length > sizeof(struct radius_attr_hdr) + strlen(CLASS_AAI_PREFIX)  )
    667                                                 && (attr->length < sizeof(struct radius_attr_hdr) + strlen(CLASS_AAI_PREFIX) + sizeof(buf))
    668                                                 && ! strncmp(attr_val, CLASS_AAI_PREFIX, strlen(CLASS_AAI_PREFIX))) {
     665                                        auth_val = attr_val + CONSTSTRLEN(CLASS_AAI_PREFIX);
     666                                        if (    (attr->length > sizeof(struct radius_attr_hdr) + CONSTSTRLEN(CLASS_AAI_PREFIX)  )
     667                                                && (attr->length < sizeof(struct radius_attr_hdr) + CONSTSTRLEN(CLASS_AAI_PREFIX) + sizeof(buf))
     668                                                && ! strncmp(attr_val, CLASS_AAI_PREFIX, CONSTSTRLEN(CLASS_AAI_PREFIX))) {
    669669                                       
    670670                                                memset(buf, 0, sizeof(buf));
    671                                                 memcpy(buf, auth_val, attr->length - sizeof(struct radius_attr_hdr) - strlen(CLASS_AAI_PREFIX));
     671                                                memcpy(buf, auth_val, attr->length - sizeof(struct radius_attr_hdr) - CONSTSTRLEN(CLASS_AAI_PREFIX));
    672672                                                if (sscanf(buf, "%u", &auth_appl) == 1) {
    673673                                                        TRACE_DEBUG(ANNOYING, "Found Class attribute with '%s' prefix (attr #%d), AAI:%u.", CLASS_AAI_PREFIX, idx, auth_appl);
     
    13011301                struct msg * str = NULL;
    13021302                struct msg_hdr * hdr = NULL;
    1303                 char * fqdn;
    1304                 char * realm;
     1303                DiamId_t fqdn;
     1304                size_t fqdn_len;
     1305                DiamId_t realm;
     1306                size_t realm_len;
    13051307                union avp_value avp_val;
    13061308               
     
    13231325
    13241326                /* Get information on the NAS */
    1325                 CHECK_FCT( rgw_clients_get_origin(cli, &fqdn, &realm) );
     1327                CHECK_FCT( rgw_clients_get_origin(cli, &fqdn, &fqdn_len, &realm, &realm_len) );
    13261328
    13271329                /* Add the Origin-Host as next AVP */
     
    13291331                memset(&avp_val, 0, sizeof(avp_val));
    13301332                avp_val.os.data = (unsigned char *)fqdn;
    1331                 avp_val.os.len = strlen(fqdn);
     1333                avp_val.os.len = fqdn_len;
    13321334                CHECK_FCT( fd_msg_avp_setvalue ( avp, &avp_val ) );
    13331335                CHECK_FCT( fd_msg_avp_add ( str, MSG_BRW_LAST_CHILD, avp) );
     
    13371339                memset(&avp_val, 0, sizeof(avp_val));
    13381340                avp_val.os.data = (unsigned char *)realm;
    1339                 avp_val.os.len = strlen(realm);
     1341                avp_val.os.len = realm_len;
    13401342                CHECK_FCT( fd_msg_avp_setvalue ( avp, &avp_val ) );
    13411343                CHECK_FCT( fd_msg_avp_add ( str, MSG_BRW_LAST_CHILD, avp) );
  • extensions/app_radgw/rgwx_auth.c

    r705 r706  
    239239        const char * prefix = "Diameter/";
    240240        size_t pref_len;
    241         uint8_t * dh = NULL;
     241        os0_t dh = NULL;
    242242        size_t dh_len = 0;
    243         uint8_t * dr = NULL;
     243        os0_t dr = NULL;
    244244        size_t dr_len = 0;
    245         uint8_t * si = NULL;
     245        os0_t si = NULL;
    246246        size_t si_len = 0;
    247         uint8_t * un = NULL;
     247        os0_t un = NULL;
    248248        size_t un_len = 0;
    249249        size_t nattr_used = 0;
     
    293293                 and/or to the NAS-Identifier attribute.  (Note that the RADIUS
    294294                 NAS-Identifier is not required to be an FQDN.)
    295                      -> done in rgw_msg_create_base.
     295                     -> done in rgw_clients_create_origin.
    296296
    297297              -  The response MUST have an Origin-AAA-Protocol AVP added,
     
    453453        /* Create the session if it is not already done */
    454454        if (*session == NULL) {
    455                 char * sess_str = NULL;
     455                os0_t sess_str = NULL;
     456                size_t sess_strlen;
    456457               
    457458                if (si_len) {
    458459                        /* We already have the Session-Id, just use it */
    459                         CHECK_FCT( fd_sess_fromsid ( (char *) /* this cast will be removed later */ si, si_len, session, NULL) );
     460                        CHECK_FCT( fd_sess_fromsid ( si, si_len, session, NULL) );
    460461                } else {
    461462                        /* Create a new Session-Id string */
    462463                       
    463                         char * fqdn;
    464                         char * realm;
     464                        DiamId_t fqdn;
     465                        size_t fqdnlen;
     466                        DiamId_t realm;
     467                        size_t realmlen;
    465468                       
    466469                        /* Get information on the RADIUS client */
    467                         CHECK_FCT( rgw_clients_get_origin(cli, &fqdn, &realm) );
     470                        CHECK_FCT( rgw_clients_get_origin(cli, &fqdn, &fqdnlen, &realm, &realmlen) );
    468471                       
    469472                        /* If we have a user name, create the new session with it */
    470473                        if (un) {
    471474                                int len;
    472                                 /* If not found, create a new Session-Id. The format is: {fqdn;hi32;lo32;username;diamid} */
     475                                /* If not found, create a new Session-Id. Our format is: {fqdn;hi32;lo32;username;diamid} */
    473476                                CHECK_MALLOC( sess_str = malloc(un_len + 1 /* ';' */ + fd_g_config->cnf_diamid_len + 1 /* '\0' */) );
    474                                 len = sprintf(sess_str, "%.*s;%s", (int)un_len, un, fd_g_config->cnf_diamid);
    475                                 CHECK_FCT( fd_sess_new(session, fqdn, sess_str, len) );
     477                                len = sprintf((char *)sess_str, "%.*s;%s", (int)un_len, un, fd_g_config->cnf_diamid);
     478                                CHECK_FCT( fd_sess_new(session, fqdn, fqdnlen, sess_str, len) );
    476479                                free(sess_str);
    477480                        } else {
     
    483486               
    484487                /* Now, add the Session-Id AVP at beginning of Diameter message */
    485                 CHECK_FCT( fd_sess_getsid(*session, &sess_str) );
     488                CHECK_FCT( fd_sess_getsid(*session, &sess_str, &sess_strlen) );
    486489               
    487490                TRACE_DEBUG(FULL, "[auth.rgwx] Translating new message for session '%s'...", sess_str);
     
    489492                /* Add the Session-Id AVP as first AVP */
    490493                CHECK_FCT( fd_msg_avp_new ( cs->dict.Session_Id, 0, &avp ) );
    491                 value.os.data = (unsigned char *)sess_str;
    492                 value.os.len = strlen(sess_str);
     494                value.os.data = sess_str;
     495                value.os.len = sess_strlen;
    493496                CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
    494497                CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_FIRST_CHILD, avp) );
     
    564567                        /* This macro converts a RADIUS attribute to a Diameter AVP of type OctetString */
    565568                        #define CONV2DIAM_STR( _dictobj_ )      \
    566                                 CHECK_PARAMS( attr->length >= 2 );                                              \
     569                                CHECK_PARAMS( attr->length >= sizeof(struct radius_attr_hdr) );                 \
    567570                                /* Create the AVP with the specified dictionary model */                        \
    568571                                CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) );                    \
    569                                 value.os.len = attr->length - 2;                                                \
    570                                 value.os.data = (unsigned char *)(attr + 1);                                    \
     572                                value.os.len = attr->length - sizeof(struct radius_attr_hdr);                   \
     573                                value.os.data = (os0_t)(attr + 1);                                              \
    571574                                CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );                               \
    572575                                /* Add the AVP in the Diameter message. */                                      \
     
    575578                        /* Same thing, for scalar AVPs of 32 bits */
    576579                        #define CONV2DIAM_32B( _dictobj_ )      \
    577                                 CHECK_PARAMS( attr->length == 6 );                                              \
     580                                CHECK_PARAMS( attr->length == sizeof(struct radius_attr_hdr)+sizeof(uint32_t) );\
    578581                                CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) );                    \
    579582                                {                                                                               \
     
    589592                        /* And the 64b version */
    590593                        #define CONV2DIAM_64B( _dictobj_ )      \
    591                                 CHECK_PARAMS( attr->length == 10);                                              \
     594                                CHECK_PARAMS( attr->length == sizeof(struct radius_attr_hdr)+sizeof(uint64_t) );\
    592595                                CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) );                    \
    593596                                {                                                                               \
     
    609612                              -  The Destination-Realm AVP is created from the information found
    610613                                 in the RADIUS User-Name attribute.
    611                                         -> done in rgw_msg_create_base
     614                                        -> done in rgw_clients_create_origin
    612615                        */
    613616                        case RADIUS_ATTR_USER_NAME:
  • extensions/app_radgw/rgwx_debug.c

    r356 r706  
    102102                fd_log_debug(" Diameter session: NULL pointer\n");
    103103        } else {
    104                 char * str;
    105                 CHECK_FCT( fd_sess_getsid(*session, &str) );
     104                os0_t str;
     105                size_t str_len;
     106                CHECK_FCT( fd_sess_getsid(*session, &str, &str_len) );
    106107
    107108                fd_log_debug(" Diameter session: %s\n", str);
  • extensions/app_radgw/rgwx_sip.c

    r705 r706  
    5858/* This macro converts a RADIUS attribute to a Diameter AVP of type OctetString */
    5959#define CONV2DIAM_STR( _dictobj_ )      \
    60         CHECK_PARAMS( attr->length >= 2 );                                              \
     60        CHECK_PARAMS( attr->length >= sizeof(struct radius_attr_hdr) );                 \
    6161        /* Create the AVP with the specified dictionary model */                        \
    6262        CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) );                    \
    63         value.os.len = attr->length - 2;                                                \
    64         value.os.data = (unsigned char *)(attr + 1);                                    \
     63        value.os.len = attr->length - sizeof(struct radius_attr_hdr);                   \
     64        value.os.data = (os0_t)(attr + 1);                                              \
    6565        CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );                               \
    6666        /* Add the AVP in the Diameter message. */                                      \
     
    6868
    6969#define CONV2DIAM_STR_AUTH( _dictobj_ ) \
    70         CHECK_PARAMS( attr->length >= 2 );                                              \
     70        CHECK_PARAMS( attr->length >= sizeof(struct radius_attr_hdr) );                 \
    7171        /* Create the AVP with the specified dictionary model */                        \
    7272        CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) );                    \
    73         value.os.len = attr->length - 2;                                                \
    74         value.os.data = (unsigned char *)(attr + 1);                                    \
     73        value.os.len = attr->length - sizeof(struct radius_attr_hdr);                   \
     74        value.os.data = (os0_t)(attr + 1);                                              \
    7575        CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );                               \
    7676        /* Add the AVP in the Diameter message. */                                      \
    77         CHECK_FCT( fd_msg_avp_add ( auth, MSG_BRW_LAST_CHILD, avp) );           \
     77        CHECK_FCT( fd_msg_avp_add ( auth, MSG_BRW_LAST_CHILD, avp) );                   \
    7878               
    7979/* Same thing, for scalar AVPs of 32 bits */
    8080#define CONV2DIAM_32B( _dictobj_ )      \
    81         CHECK_PARAMS( attr->length == 6 );                                              \
     81        CHECK_PARAMS( attr->length == sizeof(struct radius_attr_hdr)+sizeof(uint32_t) );\
    8282        CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) );                    \
    8383        {                                                                               \
    8484                uint8_t * v = (uint8_t *)(attr + 1);                                    \
    8585                value.u32  = (v[0] << 24)                                               \
    86                            | (v[1] << 16)                                               \
    87                            | (v[2] <<  8)                                               \
    88                            |  v[3] ;                                                    \
     86                           | (v[1] << 16)                                               \
     87                           | (v[2] <<  8)                                               \
     88                           |  v[3] ;                                                    \
    8989        }                                                                               \
    9090        CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );                               \
    91         CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
     91        CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );               \
    9292                               
    9393                               
     
    145145{
    146146        struct fd_list chain;
    147     char * sid;
     147    os0_t sid;
    148148    size_t sidlen;
    149     char * nonce;
     149    os0_t nonce;
    150150    size_t noncelen;
    151151   
    152152};
    153153
    154 static int nonce_add_element(char * nonce, size_t noncelen,char * sid, size_t sidlen, struct rgwp_config * state)
     154static int nonce_add_element(os0_t nonce, size_t noncelen, os0_t sid, size_t sidlen, struct rgwp_config * state)
    155155{
    156156        CHECK_PARAMS(nonce && state && sid && sidlen && noncelen);
     
    159159        CHECK_MALLOC(newelt=malloc(sizeof(noncechain)));
    160160       
    161         CHECK_MALLOC(newelt->nonce=malloc(noncelen));
    162         memcpy(newelt->nonce,nonce,noncelen);
     161        CHECK_MALLOC(newelt->nonce= os0dup(nonce, noncelen));
    163162        newelt->noncelen=noncelen;
    164163       
    165         CHECK_MALLOC(newelt->sid=malloc(sidlen));
    166         memcpy(newelt->sid,sid,sidlen);
     164        CHECK_MALLOC(newelt->sid=os0dup(sid, sidlen));
    167165        newelt->sidlen=sidlen;
    168166       
     
    198196*/
    199197//Retrieve sid from nonce
    200 static char * nonce_get_sid(char * nonce, size_t noncelen, size_t * sidlen, struct rgwp_config *state)
     198static os0_t nonce_get_sid(os0_t nonce, size_t noncelen, size_t * sidlen, struct rgwp_config *state)
    201199{
    202200        struct fd_list * li;
    203         char *sid=NULL;
     201        os0_t sid=NULL;
    204202       
    205203        CHECK_PARAMS_DO(nonce && state && noncelen && sidlen, return NULL);
    206204        *sidlen=0;
    207205       
    208         //**Start mutex
     206        // **Start mutex
    209207        CHECK_POSIX_DO(pthread_mutex_lock(&state->nonce_mutex),);
    210208        for(li=state->listnonce.next;li!=&state->listnonce;li=li->next)
     
    212210                noncechain *temp=(noncechain *)li;
    213211               
    214                 if(temp->noncelen==noncelen && strncmp(temp->nonce,nonce, noncelen)==0)
     212                if (!fd_os_cmp(temp->nonce, temp->noncelen, nonce, noncelen))
    215213                {
    216214                        fd_list_unlink (li);
     
    224222        }
    225223        CHECK_POSIX_DO(pthread_mutex_unlock(&state->nonce_mutex),);
    226         //***Stop mutex
     224        // ***Stop mutex
    227225        return sid;
    228226}
     
    230228static void nonce_deletelistnonce(struct rgwp_config *state)
    231229{
    232         //**Start mutex
     230        // **Start mutex
    233231        CHECK_POSIX_DO(pthread_mutex_lock(&state->nonce_mutex),);
    234232        while(!(FD_IS_LIST_EMPTY(&state->listnonce)) )
     
    243241        }
    244242        CHECK_POSIX_DO(pthread_mutex_unlock(&state->nonce_mutex),);
    245         //***Stop mutex
     243        // ***Stop mutex
    246244}
    247245
     
    338336        int got_Dresponse = 0;
    339337        int got_Dalgorithm = 0;
    340         char * sid = NULL;
    341         char * un=NULL;
     338        os0_t sid = NULL;
     339        size_t sidlen;
     340        os0_t un=NULL;
    342341        size_t  un_len;
    343342        size_t nattr_used = 0;
     
    352351        if(*session)
    353352        {
    354                 TRACE_DEBUG(INFO,"We are not supposed to receive a session in radSIP plugin.");
     353                TRACE_DEBUG(INFO,"INTERNAL ERROR: We are not supposed to receive a session in radSIP plugin.");
    355354                return EINVAL;
    356355        }
     
    371370                                {
    372371                                        TRACE_DEBUG(ANNOYING, "Found a User-Name attribute: '%.*s'", attr->length- sizeof(struct radius_attr_hdr), (char *)(attr+1));
    373                                         un = (char *)(attr + 1);
     372                                        un = (os0_t)(attr + 1);
    374373                                        un_len =attr->length - sizeof(struct radius_attr_hdr);
    375374                                }
     
    396395                                got_Dnonce = 1;
    397396                               
    398                                 size_t sidlen;
    399                                
    400                                 sid=nonce_get_sid((char *)(attr+1),attr->length-2,&sidlen,cs);
     397                                sid=nonce_get_sid((os0_t)(attr+1), attr->length - sizeof(struct radius_attr_hdr), &sidlen, cs);
    401398                                if(!sid)
    402399                                {
     
    406403                                CHECK_FCT(fd_sess_fromsid (sid, sidlen, session, NULL));
    407404                                free(sid);
    408                                                                
     405                                                       
    409406                               
    410407                        break;
     
    432429        if (!*session) {
    433430               
    434                 char * fqdn;
    435                 char * realm;
     431                DiamId_t fqdn;
     432                size_t fqdn_len;
     433                DiamId_t realm;
     434                size_t realm_len;
    436435               
    437436               
     
    439438               
    440439                /* Get information on the RADIUS client */
    441                 CHECK_FCT( rgw_clients_get_origin(cli, &fqdn, &realm) );
    442                
    443                 int len;
     440                CHECK_FCT( rgw_clients_get_origin(cli, &fqdn, &fqdn_len, &realm, &realm_len) );
     441               
    444442                /* Create a new Session-Id. The format is: {fqdn;hi32;lo32;username;diamid} */
    445443                CHECK_MALLOC( sid = malloc(un_len + 1 /* ';' */ + fd_g_config->cnf_diamid_len + 1 /* '\0' */) );
    446                 len = sprintf(sid, "%.*s;%s", (int)un_len, un, fd_g_config->cnf_diamid);
    447                 CHECK_FCT( fd_sess_new(session, fqdn, sid, len) );
     444                sidlen = sprintf((char *)sid, "%.*s;%s", (int)un_len, un, fd_g_config->cnf_diamid);
     445                CHECK_FCT( fd_sess_new(session, fqdn, fqdn_len, sid, sidlen) );
    448446                free(sid);
    449447        }
     
    453451       
    454452        int i = 0;
    455         if (un) {
    456                 /* Is there an '@' in the user name? We don't care for decorated NAI here */
    457                 for (i = un_len - 2; i > 0; i--) {
    458                         if (un[i] == '@') {
    459                                 i++;
    460                                 break;
    461                         }
     453       
     454        /* Is there an '@' in the user name? We don't care for decorated NAI here */
     455        for (i = un_len - 2; i > 0; i--) {
     456                if (un[i] == '@') {
     457                        i++;
     458                        break;
    462459                }
    463460        }
     461
    464462        if (i == 0) {
    465463                /* Not found in the User-Name => we use the local domain of this gateway */
    466                 value.os.data = (unsigned char *)fd_g_config->cnf_diamrlm;
     464                value.os.data = (os0_t)fd_g_config->cnf_diamrlm;
    467465                value.os.len  = fd_g_config->cnf_diamrlm_len;
    468466        } else {
    469                 value.os.data = (unsigned char *)(un + i);
     467                value.os.data = un + i;
    470468                value.os.len  = un_len - i;
    471469        }
     
    475473       
    476474        /* Now, add the Session-Id AVP at beginning of Diameter message */
    477         CHECK_FCT( fd_sess_getsid(*session, &sid) );
     475        CHECK_FCT( fd_sess_getsid(*session, &sid, &sidlen) );
    478476       
    479477        TRACE_DEBUG(FULL, "[sip.rgwx] Translating new message for session '%s'...", sid);
     
    481479        /* Add the Session-Id AVP as first AVP */
    482480        CHECK_FCT( fd_msg_avp_new ( cs->dict.Session_Id, 0, &avp ) );
    483         value.os.data = (unsigned char *)sid;
    484         value.os.len = strlen(sid);
     481        value.os.data = sid;
     482        value.os.len = sidlen;
    485483        CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
    486484        CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_FIRST_CHILD, avp) );
     
    552550                CHECK_FCT( fd_msg_avp_add ( auth_data, MSG_BRW_LAST_CHILD, auth) );
    553551        }
    554         char * temp=NULL,*sipuri=NULL;
    555552
    556553        for (idx = 0; idx < rad_req->attr_used; idx++)
     
    597594                        {
    598595                                //We extract Realm from Digest_URI
    599                                 char *realm=NULL;
    600                        
    601                                 CHECK_MALLOC(temp=malloc(attr->length -1));
    602                                 strncpy(temp, (char *)(attr + 1), attr->length -2);
    603                                 temp[attr->length-2] = '\0';
    604                        
    605                                 realm = strtok( (char *)(temp), "@" );
    606                                 realm = strtok( NULL, "@" );
    607                                 free(temp);
    608                                 temp=NULL;
     596                                DiamId_t realm=NULL;
     597                                size_t realm_len;
     598                                os0_t temp;
     599                               
     600                                temp = (os0_t)(attr + 1);
     601                               
     602                                for (i=attr->length - sizeof(struct radius_attr_hdr) - 1; i>=0; i--) {
     603                                        if (temp[i] == '@') {
     604                                                realm = (DiamId_t)temp + i + 1;
     605                                                CHECK_FCT_DO( fd_os_validate_DiameterIdentity(&realm, &realm_len, 1),
     606                                                        realm = NULL );
     607                                                break;
     608                                        }
     609                                }
     610                       
    609611                                if(realm!=NULL)
    610612                                {
    611613                                        CHECK_FCT( fd_msg_avp_new ( cs->dict.Digest_Realm, 0, &avp ) );
    612                                         value.os.data=(unsigned char *)realm;
    613                                         value.os.len=strlen(realm);
     614                                        value.os.data=(os0_t)realm;
     615                                        value.os.len=realm_len;
    614616                                        CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
    615617                                        CHECK_FCT( fd_msg_avp_add ( auth, MSG_BRW_LAST_CHILD, avp) );
     
    617619                                        //We add SIP-Server-URI AVP because SIP server is registrar (through gateway)
    618620                                        CHECK_FCT( fd_msg_avp_new ( cs->dict.SIP_Server_URI, 0, &avp ) );
    619                                         value.os.data=(unsigned char *)realm;
    620                                         value.os.len=strlen(realm);
     621                                        value.os.data=(os0_t)realm;
     622                                        value.os.len=realm_len;
    621623                                        CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
    622624                                        CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
    623625                                       
     626                                        free(realm);
    624627                                }
    625628                                else
     
    641644                        //We add SIP-Server-URI AVP because SIP server is registrar (through gateway)
    642645                        CHECK_FCT( fd_msg_avp_new ( cs->dict.SIP_Server_URI, 0, &avp ) );
    643                        
    644                        
    645                         CHECK_MALLOC(temp=malloc(attr->length -1));
    646                         strncpy(temp, (char *)(attr + 1), attr->length -2);
    647                        
    648                        
    649                         CHECK_MALLOC(sipuri=malloc(attr->length +3));
    650                         strcpy(sipuri,"sip:");
    651                         strcat(sipuri,(const char *)temp);
    652                         value.os.data=(unsigned char *)sipuri;
    653                         value.os.len=attr->length +2;
     646                        os0_t temp;
     647                        #define SIP_PREFIX      "sip:"
     648                        size_t temp_len = attr->length - sizeof(struct radius_attr_hdr) + CONSTSTRLEN(SIP_PREFIX) + 1;
     649                        CHECK_MALLOC( temp = malloc(temp_len) );
     650                        temp_len = snprintf((char *)temp, temp_len, SIP_PREFIX "%.*s", attr->length - sizeof(struct radius_attr_hdr), (char *)(attr + 1));
     651                       
     652                        value.os.data=temp;
     653                        value.os.len=temp_len;
    654654                       
    655655                        free(temp);
    656                         temp=NULL;
     656                       
    657657                        CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );
    658658                        CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) );
     
    689689                        {
    690690                                //[Note 3] If Digest-Algorithm is missing, 'MD5' is assumed.
     691                                #define DIGEST_ALGO_MD5 "MD5"
    691692                                                                               
    692693                                CHECK_FCT( fd_msg_avp_new ( cs->dict.Digest_Algorithm, 0, &avp ) );                     
    693694                                                                               
    694                                 value.os.data = (unsigned char *)"MD5";
    695                                 value.os.len = strlen((const char *)value.os.data);
     695                                value.os.data = (os0_t)DIGEST_ALGO_MD5;
     696                                value.os.len = CONSTSTRLEN(DIGEST_ALGO_MD5) - 1;
    696697                                CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) );                                       
    697698                                CHECK_FCT( fd_msg_avp_add ( auth, MSG_BRW_LAST_CHILD, avp) );   
     
    831832                                        /* Retrieve the request identified which was stored in the session */
    832833                                        if (session) {
    833                                                 char *sid=NULL;
     834                                                os0_t sid=NULL;
    834835                                                size_t sidlen;
    835                                                 fd_sess_getsid (session, &sid );
    836                                                 sidlen=strlen(sid);
     836                                                fd_sess_getsid (session, &sid, &sidlen );
    837837                                               
    838                                                 nonce_add_element((char *)ahdr->avp_value->os.data,ahdr->avp_value->os.len, sid,sidlen, cs);
     838                                                nonce_add_element(ahdr->avp_value->os.data, ahdr->avp_value->os.len, sid, sidlen, cs);
    839839                                        }
    840840                                        break;
Note: See TracChangeset for help on using the changeset viewer.