Changeset 706:4ffbc9f1e922 in freeDiameter for extensions/app_radgw
- Timestamp:
- Feb 9, 2011, 3:26:58 PM (13 years ago)
- Branch:
- default
- Phase:
- public
- Location:
- extensions/app_radgw
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
extensions/app_radgw/rgw_clients.c
r554 r706 86 86 int is_local; /* true if the RADIUS client runs on the same host -- we use Diameter Identity in that case */ 87 87 enum rgw_cli_type type; /* is it a proxy ? */ 88 char *fqdn;88 DiamId_t fqdn; /* malloc'd here */ 89 89 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 */ 92 96 size_t aliases_nb; 93 97 … … 210 214 { 211 215 struct rgw_client *tmp = NULL; 212 char buf[255]; 216 DiamId_t fqdn; 217 size_t fqdn_len; 213 218 int ret, i; 214 219 int loc = 0; … … 220 225 loc = 1; 221 226 } else { 227 char buf[255]; 222 228 223 229 /* Search FQDN for the client */ … … 227 233 return EINVAL; 228 234 } 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 } ); 229 241 } 230 242 … … 246 258 } else { 247 259 /* 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 250 263 /* Find an appropriate realm */ 251 tmp->realm = strchr( tmp->fqdn, '.');252 if (tmp->realm) 264 tmp->realm = strchr(fqdn, '.'); 265 if (tmp->realm) { 253 266 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... */ 255 270 tmp->realm = fd_g_config->cnf_diamrlm; 271 tmp->realm_len = fd_g_config->cnf_diamrlm_len; 272 } 256 273 } 257 274 … … 282 299 /* Free the data */ 283 300 for (idx = 0; idx < client->aliases_nb; idx++) 284 free(client->aliases[idx] );301 free(client->aliases[idx].name); 285 302 free(client->aliases); 286 303 free(client->fqdn); … … 532 549 int valid_nas_info = 0; 533 550 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; 537 555 char buf[REVERSE_DNS_SIZE_MAX]; /* to store DNS lookups results */ 538 556 … … 555 573 if ((attr->type == RADIUS_ATTR_NAS_IDENTIFIER) && (attr_len > 0)) { 556 574 nas_id = attr; 575 nas_id_len = attr_len; 557 576 continue; 558 577 } … … 568 587 569 588 /* Get information on this peer */ 570 CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &o r_str) );589 CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &oh_strlen, &or_str, &or_strlen) ); 571 590 572 591 goto diameter; … … 619 638 return EINVAL; 620 639 } else { 640 int ret; 641 sSS ss; 621 642 /* the peer is configured as a proxy, or running on localhost, so accept the message */ 622 sSS ss;623 643 624 644 /* In that case, the cli will be stored as Route-Record and the NAS-IP-Address as origin */ 625 645 if (!cli->is_local) { 626 646 rr_str = cli->fqdn; 647 rr_strlen = cli->fqdn_len; 627 648 } 628 649 … … 641 662 { 642 663 if (cli->is_local) { 643 CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &o r_str) );664 CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &oh_strlen, &or_str, &or_strlen) ); 644 665 goto diameter; 645 666 } … … 648 669 return EINVAL; 649 670 } ); 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; 650 684 651 oh_str = &buf[0];652 685 or_str = strchr(oh_str, '.'); 653 686 if (or_str) { … … 655 688 if (*or_str == '\0') 656 689 or_str = NULL; /* Discard this realm, we will use the local realm later */ 690 else 691 or_strlen = oh_strlen - (or_str - oh_str); 657 692 } 658 693 } 659 694 } else { 660 695 /* The attribute matches the source address, just use this in origin-host */ 661 CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &o r_str) );696 CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &oh_strlen, &or_str, &or_strlen) ); 662 697 } 663 698 … … 668 703 if (cli->is_local) { 669 704 /* Simple: we use our own configuration */ 670 CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &o r_str) );705 CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &oh_strlen, &or_str, &or_strlen) ); 671 706 goto diameter; 672 707 } … … 697 732 698 733 /* 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)) { 701 736 TRACE_DEBUG(FULL, "NAS-Identifier contains the fqdn of the client"); 702 737 found = 1; 703 738 } else { 704 739 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)) { 707 742 TRACE_DEBUG(FULL, "NAS-Identifier valid value found in the cache"); 708 743 found = 1; … … 714 749 if (found) { 715 750 /* The NAS-Identifier matches the source IP */ 716 CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &o r_str) );751 CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &oh_strlen, &or_str, &or_strlen) ); 717 752 718 753 goto diameter; … … 720 755 721 756 /* 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); 724 759 buf[nas_id->length - sizeof(struct radius_attr_hdr)] = '\0'; 725 760 … … 745 780 if (cli->type == RGW_CLI_NAS) { 746 781 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); 748 783 return EINVAL; 749 784 } else { … … 751 786 if (!cli->is_local) { 752 787 rr_str = cli->fqdn; 788 rr_strlen = cli->fqdn_len; 753 789 } 754 790 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; 755 797 or_str = strchr(oh_str, '.'); 756 798 if (or_str) { … … 758 800 if (*or_str == '\0') 759 801 or_str = NULL; /* Discard this realm, we will use the local realm later */ 802 else 803 or_strlen = oh_strlen - (or_str - oh_str); 760 804 } 761 805 } 762 806 } else { 763 807 /* 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 768 813 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, &o r_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) ); 771 816 } 772 817 } else { … … 774 819 TRACE_DEBUG(INFO, "NAS-Identifier '%s' cannot be resolved: %s. Ignoring...", buf, gai_strerror(ret)); 775 820 /* Assume this is a valid identifier for the client */ 776 CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &o r_str) );821 CHECK_FCT( rgw_clients_get_origin(cli, &oh_str, &oh_strlen, &or_str, &or_strlen) ); 777 822 } 778 823 } … … 781 826 diameter: 782 827 ASSERT(oh_str); /* If it is not defined here, there is a bug... */ 783 if (!or_str) 828 if (!or_str) { 784 829 or_str = fd_g_config->cnf_diamrlm; /* Use local realm in that case */ 830 or_strlen = fd_g_config->cnf_diamrlm_len; 831 } 785 832 786 833 /* Create an empty Diameter message so that extensions can store their AVPs */ … … 791 838 memset(&avp_val, 0, sizeof(avp_val)); 792 839 avp_val.os.data = (unsigned char *)oh_str; 793 avp_val.os.len = strlen(oh_str);840 avp_val.os.len = oh_strlen; 794 841 CHECK_FCT( fd_msg_avp_setvalue ( avp, &avp_val ) ); 795 842 CHECK_FCT( fd_msg_avp_add ( *diam, MSG_BRW_LAST_CHILD, avp) ); … … 799 846 memset(&avp_val, 0, sizeof(avp_val)); 800 847 avp_val.os.data = (unsigned char *)or_str; 801 avp_val.os.len = strlen(or_str);848 avp_val.os.len = or_strlen; 802 849 CHECK_FCT( fd_msg_avp_setvalue ( avp, &avp_val ) ); 803 850 CHECK_FCT( fd_msg_avp_add ( *diam, MSG_BRW_LAST_CHILD, avp) ); … … 807 854 memset(&avp_val, 0, sizeof(avp_val)); 808 855 avp_val.os.data = (unsigned char *)rr_str; 809 avp_val.os.len = strlen(rr_str);856 avp_val.os.len = rr_strlen; 810 857 CHECK_FCT( fd_msg_avp_setvalue ( avp, &avp_val ) ); 811 858 CHECK_FCT( fd_msg_avp_add ( *diam, MSG_BRW_LAST_CHILD, avp) ); 812 859 } 813 860 861 if (oh_free) 862 free(oh_str); 863 814 864 /* Done! */ 815 865 return 0; 816 866 } 817 867 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 );868 int 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); 822 872 823 873 if (cli->is_local) { 824 874 *fqdn = fd_g_config->cnf_diamid; 875 *fqdnlen = fd_g_config->cnf_diamid_len; 825 876 if (realm) 826 877 *realm= fd_g_config->cnf_diamrlm; 878 if (realmlen) 879 *realmlen= fd_g_config->cnf_diamrlm_len; 827 880 } else { 828 881 *fqdn = cli->fqdn; 882 *fqdnlen = cli->fqdn_len; 829 883 if (realm) 830 884 *realm= cli->realm; 885 if (realmlen) 886 *realmlen= cli->realm_len; 831 887 } 832 888 -
extensions/app_radgw/rgw_common.h
r403 r706 59 59 int rgw_clients_getkey(struct rgw_client * cli, unsigned char **key, size_t *key_len); 60 60 char * rgw_clients_id(struct rgw_client *cli); 61 int rgw_clients_get_origin(struct rgw_client *cli, char **fqdn, char **realm);61 int rgw_clients_get_origin(struct rgw_client *cli, DiamId_t *fqdn, size_t *fqdnlen, DiamId_t *realm, size_t *realmlen); 62 62 63 63 /* Each plugin must provide the following structure. */ -
extensions/app_radgw/rgw_servers.c
r553 r706 148 148 CHECK_FCT_DO( rgw_msg_parse(&buf[0], len, &msg), 149 149 { 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), ); 152 153 TRACE_DEBUG(INFO, "Discarding invalid RADIUS message from '%s'", cliname); 153 154 rgw_clients_dispose(&nas_info); -
extensions/app_radgw/rgwx_acct.c
r705 r706 306 306 const char * prefix = "Diameter/"; 307 307 size_t pref_len; 308 uint8_t *si = NULL;308 os0_t si = NULL; 309 309 size_t si_len = 0; 310 uint8_t *un = NULL;310 os0_t un = NULL; 311 311 size_t un_len = 0; 312 312 … … 487 487 /* Create the Session-Id AVP if needed */ 488 488 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) ); 490 490 491 491 TRACE_DEBUG(FULL, "[acct.rgwx] Translating new accounting message for session '%.*s'...", si_len, si); … … 663 663 char * attr_val, *auth_val; 664 664 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))) { 669 669 670 670 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)); 672 672 if (sscanf(buf, "%u", &auth_appl) == 1) { 673 673 TRACE_DEBUG(ANNOYING, "Found Class attribute with '%s' prefix (attr #%d), AAI:%u.", CLASS_AAI_PREFIX, idx, auth_appl); … … 1301 1301 struct msg * str = NULL; 1302 1302 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; 1305 1307 union avp_value avp_val; 1306 1308 … … 1323 1325 1324 1326 /* 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) ); 1326 1328 1327 1329 /* Add the Origin-Host as next AVP */ … … 1329 1331 memset(&avp_val, 0, sizeof(avp_val)); 1330 1332 avp_val.os.data = (unsigned char *)fqdn; 1331 avp_val.os.len = strlen(fqdn);1333 avp_val.os.len = fqdn_len; 1332 1334 CHECK_FCT( fd_msg_avp_setvalue ( avp, &avp_val ) ); 1333 1335 CHECK_FCT( fd_msg_avp_add ( str, MSG_BRW_LAST_CHILD, avp) ); … … 1337 1339 memset(&avp_val, 0, sizeof(avp_val)); 1338 1340 avp_val.os.data = (unsigned char *)realm; 1339 avp_val.os.len = strlen(realm);1341 avp_val.os.len = realm_len; 1340 1342 CHECK_FCT( fd_msg_avp_setvalue ( avp, &avp_val ) ); 1341 1343 CHECK_FCT( fd_msg_avp_add ( str, MSG_BRW_LAST_CHILD, avp) ); -
extensions/app_radgw/rgwx_auth.c
r705 r706 239 239 const char * prefix = "Diameter/"; 240 240 size_t pref_len; 241 uint8_t *dh = NULL;241 os0_t dh = NULL; 242 242 size_t dh_len = 0; 243 uint8_t *dr = NULL;243 os0_t dr = NULL; 244 244 size_t dr_len = 0; 245 uint8_t *si = NULL;245 os0_t si = NULL; 246 246 size_t si_len = 0; 247 uint8_t *un = NULL;247 os0_t un = NULL; 248 248 size_t un_len = 0; 249 249 size_t nattr_used = 0; … … 293 293 and/or to the NAS-Identifier attribute. (Note that the RADIUS 294 294 NAS-Identifier is not required to be an FQDN.) 295 -> done in rgw_ msg_create_base.295 -> done in rgw_clients_create_origin. 296 296 297 297 - The response MUST have an Origin-AAA-Protocol AVP added, … … 453 453 /* Create the session if it is not already done */ 454 454 if (*session == NULL) { 455 char * sess_str = NULL; 455 os0_t sess_str = NULL; 456 size_t sess_strlen; 456 457 457 458 if (si_len) { 458 459 /* 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) ); 460 461 } else { 461 462 /* Create a new Session-Id string */ 462 463 463 char * fqdn; 464 char * realm; 464 DiamId_t fqdn; 465 size_t fqdnlen; 466 DiamId_t realm; 467 size_t realmlen; 465 468 466 469 /* 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) ); 468 471 469 472 /* If we have a user name, create the new session with it */ 470 473 if (un) { 471 474 int len; 472 /* If not found, create a new Session-Id. Theformat is: {fqdn;hi32;lo32;username;diamid} */475 /* If not found, create a new Session-Id. Our format is: {fqdn;hi32;lo32;username;diamid} */ 473 476 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) ); 476 479 free(sess_str); 477 480 } else { … … 483 486 484 487 /* 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) ); 486 489 487 490 TRACE_DEBUG(FULL, "[auth.rgwx] Translating new message for session '%s'...", sess_str); … … 489 492 /* Add the Session-Id AVP as first AVP */ 490 493 CHECK_FCT( fd_msg_avp_new ( cs->dict.Session_Id, 0, &avp ) ); 491 value.os.data = (unsigned char *)sess_str;492 value.os.len = s trlen(sess_str);494 value.os.data = sess_str; 495 value.os.len = sess_strlen; 493 496 CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); 494 497 CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_FIRST_CHILD, avp) ); … … 564 567 /* This macro converts a RADIUS attribute to a Diameter AVP of type OctetString */ 565 568 #define CONV2DIAM_STR( _dictobj_ ) \ 566 CHECK_PARAMS( attr->length >= 2 );\569 CHECK_PARAMS( attr->length >= sizeof(struct radius_attr_hdr) ); \ 567 570 /* Create the AVP with the specified dictionary model */ \ 568 571 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); \ 571 574 CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); \ 572 575 /* Add the AVP in the Diameter message. */ \ … … 575 578 /* Same thing, for scalar AVPs of 32 bits */ 576 579 #define CONV2DIAM_32B( _dictobj_ ) \ 577 CHECK_PARAMS( attr->length == 6 );\580 CHECK_PARAMS( attr->length == sizeof(struct radius_attr_hdr)+sizeof(uint32_t) );\ 578 581 CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) ); \ 579 582 { \ … … 589 592 /* And the 64b version */ 590 593 #define CONV2DIAM_64B( _dictobj_ ) \ 591 CHECK_PARAMS( attr->length == 10);\594 CHECK_PARAMS( attr->length == sizeof(struct radius_attr_hdr)+sizeof(uint64_t) );\ 592 595 CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) ); \ 593 596 { \ … … 609 612 - The Destination-Realm AVP is created from the information found 610 613 in the RADIUS User-Name attribute. 611 -> done in rgw_ msg_create_base614 -> done in rgw_clients_create_origin 612 615 */ 613 616 case RADIUS_ATTR_USER_NAME: -
extensions/app_radgw/rgwx_debug.c
r356 r706 102 102 fd_log_debug(" Diameter session: NULL pointer\n"); 103 103 } 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) ); 106 107 107 108 fd_log_debug(" Diameter session: %s\n", str); -
extensions/app_radgw/rgwx_sip.c
r705 r706 58 58 /* This macro converts a RADIUS attribute to a Diameter AVP of type OctetString */ 59 59 #define CONV2DIAM_STR( _dictobj_ ) \ 60 CHECK_PARAMS( attr->length >= 2 );\60 CHECK_PARAMS( attr->length >= sizeof(struct radius_attr_hdr) ); \ 61 61 /* Create the AVP with the specified dictionary model */ \ 62 62 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); \ 65 65 CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); \ 66 66 /* Add the AVP in the Diameter message. */ \ … … 68 68 69 69 #define CONV2DIAM_STR_AUTH( _dictobj_ ) \ 70 CHECK_PARAMS( attr->length >= 2 );\70 CHECK_PARAMS( attr->length >= sizeof(struct radius_attr_hdr) ); \ 71 71 /* Create the AVP with the specified dictionary model */ \ 72 72 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); \ 75 75 CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); \ 76 76 /* 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) ); \ 78 78 79 79 /* Same thing, for scalar AVPs of 32 bits */ 80 80 #define CONV2DIAM_32B( _dictobj_ ) \ 81 CHECK_PARAMS( attr->length == 6 );\81 CHECK_PARAMS( attr->length == sizeof(struct radius_attr_hdr)+sizeof(uint32_t) );\ 82 82 CHECK_FCT( fd_msg_avp_new ( cs->dict._dictobj_, 0, &avp ) ); \ 83 83 { \ 84 84 uint8_t * v = (uint8_t *)(attr + 1); \ 85 85 value.u32 = (v[0] << 24) \ 86 87 88 86 | (v[1] << 16) \ 87 | (v[2] << 8) \ 88 | v[3] ; \ 89 89 } \ 90 90 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) ); \ 92 92 93 93 … … 145 145 { 146 146 struct fd_list chain; 147 char *sid;147 os0_t sid; 148 148 size_t sidlen; 149 char *nonce;149 os0_t nonce; 150 150 size_t noncelen; 151 151 152 152 }; 153 153 154 static int nonce_add_element( char * nonce, size_t noncelen,char *sid, size_t sidlen, struct rgwp_config * state)154 static int nonce_add_element(os0_t nonce, size_t noncelen, os0_t sid, size_t sidlen, struct rgwp_config * state) 155 155 { 156 156 CHECK_PARAMS(nonce && state && sid && sidlen && noncelen); … … 159 159 CHECK_MALLOC(newelt=malloc(sizeof(noncechain))); 160 160 161 CHECK_MALLOC(newelt->nonce=malloc(noncelen)); 162 memcpy(newelt->nonce,nonce,noncelen); 161 CHECK_MALLOC(newelt->nonce= os0dup(nonce, noncelen)); 163 162 newelt->noncelen=noncelen; 164 163 165 CHECK_MALLOC(newelt->sid=malloc(sidlen)); 166 memcpy(newelt->sid,sid,sidlen); 164 CHECK_MALLOC(newelt->sid=os0dup(sid, sidlen)); 167 165 newelt->sidlen=sidlen; 168 166 … … 198 196 */ 199 197 //Retrieve sid from nonce 200 static char * nonce_get_sid(char *nonce, size_t noncelen, size_t * sidlen, struct rgwp_config *state)198 static os0_t nonce_get_sid(os0_t nonce, size_t noncelen, size_t * sidlen, struct rgwp_config *state) 201 199 { 202 200 struct fd_list * li; 203 char *sid=NULL;201 os0_t sid=NULL; 204 202 205 203 CHECK_PARAMS_DO(nonce && state && noncelen && sidlen, return NULL); 206 204 *sidlen=0; 207 205 208 // **Start mutex206 // **Start mutex 209 207 CHECK_POSIX_DO(pthread_mutex_lock(&state->nonce_mutex),); 210 208 for(li=state->listnonce.next;li!=&state->listnonce;li=li->next) … … 212 210 noncechain *temp=(noncechain *)li; 213 211 214 if (temp->noncelen==noncelen && strncmp(temp->nonce,nonce, noncelen)==0)212 if (!fd_os_cmp(temp->nonce, temp->noncelen, nonce, noncelen)) 215 213 { 216 214 fd_list_unlink (li); … … 224 222 } 225 223 CHECK_POSIX_DO(pthread_mutex_unlock(&state->nonce_mutex),); 226 // ***Stop mutex224 // ***Stop mutex 227 225 return sid; 228 226 } … … 230 228 static void nonce_deletelistnonce(struct rgwp_config *state) 231 229 { 232 // **Start mutex230 // **Start mutex 233 231 CHECK_POSIX_DO(pthread_mutex_lock(&state->nonce_mutex),); 234 232 while(!(FD_IS_LIST_EMPTY(&state->listnonce)) ) … … 243 241 } 244 242 CHECK_POSIX_DO(pthread_mutex_unlock(&state->nonce_mutex),); 245 // ***Stop mutex243 // ***Stop mutex 246 244 } 247 245 … … 338 336 int got_Dresponse = 0; 339 337 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; 342 341 size_t un_len; 343 342 size_t nattr_used = 0; … … 352 351 if(*session) 353 352 { 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."); 355 354 return EINVAL; 356 355 } … … 371 370 { 372 371 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); 374 373 un_len =attr->length - sizeof(struct radius_attr_hdr); 375 374 } … … 396 395 got_Dnonce = 1; 397 396 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); 401 398 if(!sid) 402 399 { … … 406 403 CHECK_FCT(fd_sess_fromsid (sid, sidlen, session, NULL)); 407 404 free(sid); 408 405 409 406 410 407 break; … … 432 429 if (!*session) { 433 430 434 char * fqdn; 435 char * realm; 431 DiamId_t fqdn; 432 size_t fqdn_len; 433 DiamId_t realm; 434 size_t realm_len; 436 435 437 436 … … 439 438 440 439 /* 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 444 442 /* Create a new Session-Id. The format is: {fqdn;hi32;lo32;username;diamid} */ 445 443 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) ); 448 446 free(sid); 449 447 } … … 453 451 454 452 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; 462 459 } 463 460 } 461 464 462 if (i == 0) { 465 463 /* 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; 467 465 value.os.len = fd_g_config->cnf_diamrlm_len; 468 466 } else { 469 value.os.data = (unsigned char *)(un + i);467 value.os.data = un + i; 470 468 value.os.len = un_len - i; 471 469 } … … 475 473 476 474 /* 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) ); 478 476 479 477 TRACE_DEBUG(FULL, "[sip.rgwx] Translating new message for session '%s'...", sid); … … 481 479 /* Add the Session-Id AVP as first AVP */ 482 480 CHECK_FCT( fd_msg_avp_new ( cs->dict.Session_Id, 0, &avp ) ); 483 value.os.data = (unsigned char *)sid;484 value.os.len = s trlen(sid);481 value.os.data = sid; 482 value.os.len = sidlen; 485 483 CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); 486 484 CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_FIRST_CHILD, avp) ); … … 552 550 CHECK_FCT( fd_msg_avp_add ( auth_data, MSG_BRW_LAST_CHILD, auth) ); 553 551 } 554 char * temp=NULL,*sipuri=NULL;555 552 556 553 for (idx = 0; idx < rad_req->attr_used; idx++) … … 597 594 { 598 595 //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 609 611 if(realm!=NULL) 610 612 { 611 613 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; 614 616 CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); 615 617 CHECK_FCT( fd_msg_avp_add ( auth, MSG_BRW_LAST_CHILD, avp) ); … … 617 619 //We add SIP-Server-URI AVP because SIP server is registrar (through gateway) 618 620 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; 621 623 CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); 622 624 CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) ); 623 625 626 free(realm); 624 627 } 625 628 else … … 641 644 //We add SIP-Server-URI AVP because SIP server is registrar (through gateway) 642 645 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; 654 654 655 655 free(temp); 656 temp=NULL;656 657 657 CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); 658 658 CHECK_FCT( fd_msg_avp_add ( *diam_fw, MSG_BRW_LAST_CHILD, avp) ); … … 689 689 { 690 690 //[Note 3] If Digest-Algorithm is missing, 'MD5' is assumed. 691 #define DIGEST_ALGO_MD5 "MD5" 691 692 692 693 CHECK_FCT( fd_msg_avp_new ( cs->dict.Digest_Algorithm, 0, &avp ) ); 693 694 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; 696 697 CHECK_FCT( fd_msg_avp_setvalue ( avp, &value ) ); 697 698 CHECK_FCT( fd_msg_avp_add ( auth, MSG_BRW_LAST_CHILD, avp) ); … … 831 832 /* Retrieve the request identified which was stored in the session */ 832 833 if (session) { 833 char *sid=NULL;834 os0_t sid=NULL; 834 835 size_t sidlen; 835 fd_sess_getsid (session, &sid ); 836 sidlen=strlen(sid); 836 fd_sess_getsid (session, &sid, &sidlen ); 837 837 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); 839 839 } 840 840 break;
Note: See TracChangeset
for help on using the changeset viewer.