/* * Check from Radius if URI user given as argument belongs to a local user. * If so, loads AVPs based on reply items returned from Radius. */ int radius_does_uri_user_exist(struct sip_msg* _m, str user) { static char msg[4096]; VALUE_PAIR *send, *received; uint32_t service; int res, extra_cnt, offset, i; send = received = 0; if (!rc_avpair_add(rh, &send, uri_attrs[SA_USER_NAME].v, user.s, user.len, 0)) { LM_ERR("in adding SA_USER_NAME\n"); return -1; } service = uri_vals[UV_CALL_CHECK].v; if (!rc_avpair_add(rh, &send, uri_attrs[SA_SERVICE_TYPE].v, &service, -1, 0)) { LM_ERR("in adding SA_SERVICE_TYPE <%u>\n", service); goto error; } /* Add extra attributes */ extra_cnt = extra2strar(uri_extra, _m, val_arr); if (extra_cnt == -1) { LM_ERR("in getting values of group extra attributes\n"); goto error; } offset = SA_STATIC_MAX; for (i = 0; i < extra_cnt; i++) { if (val_arr[i].len == -1) { /* Add integer attribute */ ADD_EXTRA_AVPAIR(uri_attrs, offset+i, &(val_arr[i].s), val_arr[i].len ); } else { /* Add string attribute */ ADD_EXTRA_AVPAIR(uri_attrs, offset+i, val_arr[i].s, val_arr[i].len ); } } if ((res = rc_auth(rh, 0, send, &received, msg)) == OK_RC) { LM_DBG("success\n"); rc_avpair_free(send); generate_avps(uri_attrs, received); rc_avpair_free(received); return 1; } else { rc_avpair_free(send); rc_avpair_free(received); #ifdef REJECT_RC if (res == REJECT_RC) { LM_DBG("rejected\n"); return -1; } else { LM_ERR("failure\n"); return -2; } #else LM_DBG("failure\n"); return -1; #endif } error: rc_avpair_free(send); return -1; }
/* * Check from Radius if URI, whose user and host parts are given as * arguments, exists. If so, loads AVPs based on reply items returned * from Radius. If use_sip_uri_host module parameter has non-zero value, * user is send in SA_USER_NAME attribute and host in SA_SIP_URI_HOST * attribute. If is has zero value, user@host is send in SA_USER_NAME * attribute. */ int radius_does_uri_user_host_exist(struct sip_msg* _m, str user, str host) { char* at, *user_host; VALUE_PAIR *send, *received; uint32_t service; static char msg[4096]; int extra_cnt, offset, i, res; send = received = 0; user_host = 0; if (!use_sip_uri_host) { /* Send user@host in SA_USER_NAME attr */ user_host = (char*)pkg_malloc(user.len + host.len + 2); if (!user_host) { LM_ERR("no more pkg memory\n"); return -1; } at = user_host; memcpy(at, user.s, user.len); at += user.len; *at = '@'; at++; memcpy(at , host.s, host.len); at += host.len; *at = '\0'; if (!rc_avpair_add(rh, &send, uri_attrs[SA_USER_NAME].v, user_host, -1, 0)) { LM_ERR("in adding SA_USER_NAME\n"); pkg_free(user_host); return -1; } } else { /* Send user in SA_USER_NAME attribute and host in SA_SIP_URI_HOST attribute */ if (!rc_avpair_add(rh, &send, uri_attrs[SA_USER_NAME].v, user.s, user.len, 0)) { LM_ERR("adding User-Name failed\n"); return -1; } if (!rc_avpair_add(rh, &send, uri_attrs[SA_SIP_URI_HOST].v, host.s, host.len, 0)) { LM_ERR("adding SIP-URI-Host failed\n"); goto error; } } service = uri_vals[UV_CALL_CHECK].v; if (!rc_avpair_add(rh, &send, uri_attrs[SA_SERVICE_TYPE].v, &service, -1, 0)) { LM_ERR("in adding SA_SERVICE_TYPE <%u>\n", service); goto error; } /* Add extra attributes */ extra_cnt = extra2strar(uri_extra, _m, val_arr); if (extra_cnt == -1) { LM_ERR("in getting values of group extra attributes\n"); goto error; } offset = SA_STATIC_MAX; for (i = 0; i < extra_cnt; i++) { if (val_arr[i].len == -1) { /* Add integer attribute */ ADD_EXTRA_AVPAIR(uri_attrs, offset+i, &(val_arr[i].s), val_arr[i].len ); } else { /* Add string attribute */ ADD_EXTRA_AVPAIR(uri_attrs, offset+i, val_arr[i].s, val_arr[i].len ); } } if ((res = rc_auth(rh, 0, send, &received, msg)) == OK_RC) { LM_DBG("success\n"); if (user_host) pkg_free(user_host); rc_avpair_free(send); generate_avps(uri_attrs, received); rc_avpair_free(received); return 1; } else { if (user_host) pkg_free(user_host); rc_avpair_free(send); rc_avpair_free(received); #ifdef REJECT_RC if (res == REJECT_RC) { LM_DBG("rejected\n"); return -1; } else { LM_ERR("failure\n"); return -2; } #else LM_DBG("failure\n"); return -1; #endif } error: rc_avpair_free(send); if (user_host) pkg_free(user_host); return -1; }
/* * Loads from Radius callee's AVPs based on pvar argument. * Returns 1 if Radius request succeeded and -1 otherwise. */ int radius_load_callee_avps(struct sip_msg* _m, char* _callee, char* _s2) { str user; VALUE_PAIR *send, *received; uint32_t service; static char msg[4096]; int extra_cnt, offset, i, res; send = received = 0; if ((_callee == NULL) || (fixup_get_svalue(_m, (gparam_p)_callee, &user) != 0)) { LM_ERR("invalid callee parameter"); return -1; } if (!rc_avpair_add(rh, &send, callee_attrs[SA_USER_NAME].v, user.s, user.len, 0)) { LM_ERR("in adding SA_USER_NAME\n"); return -1; } service = callee_vals[EV_SIP_CALLEE_AVPS].v; if (!rc_avpair_add(rh, &send, callee_attrs[SA_SERVICE_TYPE].v, &service, -1, 0)) { LM_ERR("in adding SA_SERVICE_TYPE <%u>\n", service); goto error; } /* Add extra attributes */ extra_cnt = extra2strar(callee_extra, _m, val_arr); if (extra_cnt == -1) { LM_ERR("in getting values of callee extra attributes\n"); goto error; } offset = SA_STATIC_MAX; for (i = 0; i < extra_cnt; i++) { if (val_arr[i].len == -1) { /* Add integer attribute */ ADD_EXTRA_AVPAIR(callee_attrs, offset+i, &(val_arr[i].s), val_arr[i].len ); } else { /* Add string attribute */ ADD_EXTRA_AVPAIR(callee_attrs, offset+i, val_arr[i].s, val_arr[i].len ); } } if ((res = rc_auth(rh, 0, send, &received, msg)) == OK_RC) { LM_DBG("success\n"); rc_avpair_free(send); generate_avps(callee_attrs, received); rc_avpair_free(received); return 1; } else { rc_avpair_free(send); rc_avpair_free(received); #ifdef REJECT_RC if (res == REJECT_RC) { LM_DBG("rejected\n"); return -1; } else { LM_ERR("failure\n"); return -2; } #else LM_DBG("failure\n"); return -1; #endif } error: rc_avpair_free(send); return -1; }
/* * Check from Radius if a user belongs to a group. User-Name is given in * first string argment that may contain pseudo variables. SIP-Group is * given in second string variable that may not contain pseudo variables. * Service-Type is Group-Check. */ int radius_is_user_in(struct sip_msg* _m, char* _user, char* _group) { str user, *group; VALUE_PAIR *send, *received; uint32_t service; static char msg[4096]; int extra_cnt, offset, i, res; send = received = 0; if ((_user == NULL) || (fixup_get_svalue(_m, (gparam_p)_user, &user) != 0)) { LM_ERR("invalid user parameter"); return -1; } if (!rc_avpair_add(rh, &send, group_attrs[SA_USER_NAME].v, user.s, user.len, 0)) { LM_ERR("in adding SA_USER_NAME\n"); return -1; } group = (str*)_group; if ((group == NULL) || (group->len == 0)) { LM_ERR("invalid group parameter"); goto error; } if (!rc_avpair_add(rh, &send, group_attrs[SA_SIP_GROUP].v, group->s, group->len, 0)) { LM_ERR("in adding SA_SIP_GROUP\n"); goto error; } service = group_vals[GV_GROUP_CHECK].v; if (!rc_avpair_add(rh, &send, group_attrs[SA_SERVICE_TYPE].v, &service, -1, 0)) { LM_ERR("in adding SA_SERVICE_TYPE <%u>\n", service); goto error; } /* Add extra attributes */ extra_cnt = extra2strar(group_extra, _m, val_arr); if (extra_cnt == -1) { LM_ERR("in getting values of group extra attributes\n"); goto error; } offset = SA_STATIC_MAX; for (i = 0; i < extra_cnt; i++) { if (val_arr[i].len == -1) { /* Add integer attribute */ ADD_EXTRA_AVPAIR(group_attrs, offset+i, &(val_arr[i].s), val_arr[i].len ); } else { /* Add string attribute */ ADD_EXTRA_AVPAIR(group_attrs, offset+i, val_arr[i].s, val_arr[i].len ); } } if ((res = rc_auth(rh, 0, send, &received, msg)) == OK_RC) { LM_DBG("success\n"); rc_avpair_free(send); generate_avps(group_attrs, received); rc_avpair_free(received); return 1; } else { rc_avpair_free(send); rc_avpair_free(received); #ifdef REJECT_RC if (res == REJECT_RC) { LM_DBG("rejected\n"); return -1; } else { LM_ERR("failure\n"); return -2; } #else LM_DBG("failure\n"); return -1; #endif } error: rc_avpair_free(send); return -1; }
/* * This function creates and submits radius authentication request as per * draft-sterman-aaa-sip-00.txt. In addition, _user parameter is included * in the request as value of a SER specific attribute type SIP-URI-User, * which can be be used as a check item in the request. Service type of * the request is Authenticate-Only. */ int radius_authorize_sterman(struct sip_msg* _msg, dig_cred_t* _cred, str* _method, str* _user) { static char msg[4096]; VALUE_PAIR *send, *received; uint32_t service; str method, user, user_name; str *ruri; int extra_cnt, offset, i; send = received = 0; if (!(_cred && _method && _user)) { LM_ERR("invalid parameter value\n"); return -1; } method = *_method; user = *_user; /* * Add all the user digest parameters according to the qop defined. * Most devices tested only offer support for the simplest digest. */ if (_cred->username.domain.len || !append_realm_to_username) { if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, _cred->username.whole.s, _cred->username.whole.len, 0)) { LM_ERR("unable to add User-Name attribute\n"); goto err; } } else { user_name.len = _cred->username.user.len + _cred->realm.len + 1; user_name.s = pkg_malloc(user_name.len); if (!user_name.s) { LM_ERR("no pkg memory left\n"); return -3; } memcpy(user_name.s, _cred->username.whole.s, _cred->username.whole.len); user_name.s[_cred->username.whole.len] = '@'; memcpy(user_name.s + _cred->username.whole.len + 1, _cred->realm.s, _cred->realm.len); if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, user_name.s, user_name.len, 0)) { LM_ERR("unable to add User-Name attribute\n"); pkg_free(user_name.s); goto err; } pkg_free(user_name.s); } if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_USER_NAME].v, _cred->username.whole.s, _cred->username.whole.len, 0)) { LM_ERR("unable to add Digest-User-Name attribute\n"); goto err; } if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_REALM].v, _cred->realm.s, _cred->realm.len, 0)) { LM_ERR("unable to add Digest-Realm attribute\n"); goto err; } if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_NONCE].v, _cred->nonce.s, _cred->nonce.len, 0)) { LM_ERR("unable to add Digest-Nonce attribute\n"); goto err; } if (use_ruri_flag < 0 || isflagset(_msg, use_ruri_flag) != 1) { ruri = &_cred->uri; } else { ruri = GET_RURI(_msg); } if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_URI].v, ruri->s, ruri->len, 0)) { LM_ERR("unable to add Digest-URI attribute\n"); goto err; } if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_METHOD].v, method.s, method.len, 0)) { LM_ERR("unable to add Digest-Method attribute\n"); goto err; } /* * Add the additional authentication fields according to the QOP. */ if (_cred->qop.qop_parsed == QOP_AUTH) { if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_QOP].v, "auth", 4, 0)) { LM_ERR("unable to add Digest-QOP attribute\n"); goto err; } if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_NONCE_COUNT].v, _cred->nc.s, _cred->nc.len, 0)) { LM_ERR("unable to add Digest-CNonce-Count attribute\n"); goto err; } if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_CNONCE].v, _cred->cnonce.s, _cred->cnonce.len, 0)) { LM_ERR("unable to add Digest-CNonce attribute\n"); goto err; } } else if (_cred->qop.qop_parsed == QOP_AUTHINT) { if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_QOP].v, "auth-int", 8, 0)) { LM_ERR("unable to add Digest-QOP attribute\n"); goto err; } if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_NONCE_COUNT].v, _cred->nc.s, _cred->nc.len, 0)) { LM_ERR("unable to add Digest-Nonce-Count attribute\n"); goto err; } if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_CNONCE].v, _cred->cnonce.s, _cred->cnonce.len, 0)) { LM_ERR("unable to add Digest-CNonce attribute\n"); goto err; } if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_BODY_DIGEST].v, _cred->opaque.s, _cred->opaque.len, 0)) { LM_ERR("unable to add Digest-Body-Digest attribute\n"); goto err; } } else { /* send nothing for qop == "" */ } /* Add the response... What to calculate against... */ if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_RESPONSE].v, _cred->response.s, _cred->response.len, 0)) { LM_ERR("unable to add Digest-Response attribute\n"); goto err; } /* Indicate the service type, Authenticate only in our case */ service = vals[V_SIP_SESSION].v; if (!rc_avpair_add(rh, &send, attrs[A_SERVICE_TYPE].v, &service, -1, 0)) { LM_ERR("unable to add Service-Type attribute\n"); goto err; } /* Add SIP URI as a check item */ if (!rc_avpair_add(rh,&send,attrs[A_SIP_URI_USER].v,user.s,user.len,0)) { LM_ERR("unable to add Sip-URI-User attribute\n"); goto err; } if (attrs[A_CISCO_AVPAIR].n != NULL) { if (add_cisco_vsa(&send, _msg)) { goto err; } } /* Add extra attributes */ extra_cnt = extra2strar(auth_extra, _msg, val_arr); if (extra_cnt == -1) { LM_ERR("in getting values of extra attributes\n"); goto err; } offset = A_MAX; for (i = 0; i < extra_cnt; i++) { if (val_arr[i].len == -1) { /* Add integer attribute */ ADD_EXTRA_AVPAIR(attrs, offset+i, &(val_arr[i].s), val_arr[i].len ); } else { /* Add string attribute */ ADD_EXTRA_AVPAIR(attrs, offset+i, val_arr[i].s, val_arr[i].len ); } } /* Send request */ if ((i = rc_auth(rh, SIP_PORT, send, &received, msg)) == OK_RC) { LM_DBG("Success\n"); rc_avpair_free(send); send = 0; generate_avps(received); rc_avpair_free(received); return 1; } else { #ifdef REJECT_RC if (i == REJECT_RC) { LM_DBG("Failure\n"); goto err; } #endif LM_ERR("authorization failed. RC auth returned %d\n", i); } err: if (send) rc_avpair_free(send); if (received) rc_avpair_free(received); return -1; }