00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "../../mem/mem.h"
00034 #include "../../dprint.h"
00035 #include "../../usr_avp.h"
00036 #include "../../radius.h"
00037 #include "../../ut.h"
00038 #include "../auth/api.h"
00039 #include "sterman.h"
00040 #include "authrad_mod.h"
00041 #include "extra.h"
00042
00043 #include <stdlib.h>
00044 #include <string.h>
00045
00046
00047
00048 static str val_arr[MAX_EXTRA];
00049
00050
00051
00052 #define ADD_EXTRA_AVPAIR(_attrs, _attr, _val, _len) \
00053 do { \
00054 if ((_len) != 0) { \
00055 if ((_len) == -1) { \
00056 if (_attrs[_attr].t != PW_TYPE_INTEGER) { \
00057 LM_ERR("attribute %d is not of type integer\n", \
00058 _attrs[_attr].v); \
00059 goto err; \
00060 } \
00061 } \
00062 if (!rc_avpair_add( rh, &send, _attrs[_attr].v, _val, _len, 0)) { \
00063 LM_ERR("failed to add %s, %d\n", _attrs[_attr].n, _attr); \
00064 goto err; \
00065 } \
00066 } \
00067 }while(0)
00068
00069
00070 static inline int extract_avp(VALUE_PAIR* vp, unsigned short *flags,
00071 int_str *name, int_str *value)
00072 {
00073 static str names, values;
00074 unsigned int r;
00075 char *p;
00076 char *end;
00077
00078
00079 if (vp->lvalue==0 || vp->strvalue==0)
00080 goto error;
00081
00082 p = vp->strvalue;
00083 end = vp->strvalue + vp->lvalue;
00084
00085 LM_DBG("string is <%.*s>\n", (int)(long)(end-p), p);
00086
00087
00088 if (*p!='#') {
00089
00090 *flags |= AVP_NAME_STR;
00091 names.s = p;
00092 } else {
00093 names.s = ++p;
00094 }
00095
00096 names.len = 0;
00097 while( p<end && *p!=':' && *p!='#')
00098 p++;
00099 if (names.s==p || p==end) {
00100 LM_ERR("empty AVP name\n");
00101 goto error;
00102 }
00103 names.len = p - names.s;
00104 LM_DBG("AVP name is <%.*s>\n", names.len, names.s);
00105
00106
00107 if (*p!='#') {
00108
00109 *flags |= AVP_VAL_STR;
00110 }
00111 values.s = ++p;
00112 values.len = end-values.s;
00113 if (values.len==0) {
00114 LM_ERR("empty AVP value\n");
00115 goto error;
00116 }
00117 LM_DBG("AVP val is <%.*s>\n", values.len, values.s);
00118
00119 if ( !((*flags)&AVP_NAME_STR) ) {
00120
00121 if (str2int(&names,&r)!=0 ) {
00122 LM_ERR("invalid AVP ID '%.*s'\n", names.len,names.s);
00123 goto error;
00124 }
00125 name->n = (int)r;
00126 } else {
00127 name->s = names;
00128 }
00129
00130 if ( !((*flags)&AVP_VAL_STR) ) {
00131
00132 if (str2int(&values,&r)!=0 ) {
00133 LM_ERR("invalid AVP numrical value '%.*s'\n", values.len,values.s);
00134 goto error;
00135 }
00136 value->n = (int)r;
00137 } else {
00138 value->s = values;
00139 }
00140
00141 return 0;
00142 error:
00143 return -1;
00144 }
00145
00146
00147
00148
00149
00150 static int generate_avps(VALUE_PAIR* received)
00151 {
00152 int_str name, val;
00153 unsigned short flags;
00154 VALUE_PAIR *vp;
00155
00156 vp = received;
00157
00158 LM_DBG("getting SIP AVPs from avpair %d\n", attrs[A_SIP_AVP].v);
00159
00160 for( ; (vp=rc_avpair_get(vp,attrs[A_SIP_AVP].v,0)) ; vp=vp->next) {
00161 flags = 0;
00162 if (extract_avp( vp, &flags, &name, &val)!=0 )
00163 continue;
00164 if (add_avp( flags, name, val) < 0) {
00165 LM_ERR("unable to create a new AVP\n");
00166 } else {
00167 LM_DBG("AVP '%.*s'/%d='%.*s'/%d has been added\n",
00168 (flags&AVP_NAME_STR)?name.s.len:4,
00169 (flags&AVP_NAME_STR)?name.s.s:"null",
00170 (flags&AVP_NAME_STR)?0:name.n,
00171 (flags&AVP_VAL_STR)?val.s.len:4,
00172 (flags&AVP_VAL_STR)?val.s.s:"null",
00173 (flags&AVP_VAL_STR)?0:val.n );
00174 }
00175 }
00176
00177 return 0;
00178 }
00179
00180
00181 static int add_cisco_vsa(VALUE_PAIR** send, struct sip_msg* msg)
00182 {
00183 str callid;
00184
00185 if (!msg->callid && parse_headers(msg, HDR_CALLID_F, 0) == -1) {
00186 LM_ERR("cannot parse Call-ID header field\n");
00187 return -1;
00188 }
00189
00190 if (!msg->callid) {
00191 LM_ERR("call-ID header field not found\n");
00192 return -1;
00193 }
00194
00195 callid.len = msg->callid->body.len + 8;
00196 callid.s = pkg_malloc(callid.len);
00197 if (callid.s == NULL) {
00198 LM_ERR("no pkg memory left\n");
00199 return -1;
00200 }
00201
00202 memcpy(callid.s, "call-id=", 8);
00203 memcpy(callid.s + 8, msg->callid->body.s, msg->callid->body.len);
00204
00205 if (rc_avpair_add(rh, send, attrs[A_CISCO_AVPAIR].v, callid.s,
00206 callid.len, VENDOR(attrs[A_CISCO_AVPAIR].v)) == 0) {
00207 LM_ERR("unable to add Cisco-AVPair attribute\n");
00208 pkg_free(callid.s);
00209 return -1;
00210 }
00211
00212 pkg_free(callid.s);
00213 return 0;
00214 }
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 int radius_authorize_sterman(struct sip_msg* _msg, dig_cred_t* _cred, str* _method, str* _user)
00225 {
00226 static char msg[4096];
00227 VALUE_PAIR *send, *received;
00228 uint32_t service;
00229 str method, user, user_name;
00230 str *ruri;
00231 int extra_cnt, offset, i;
00232
00233 send = received = 0;
00234
00235 if (!(_cred && _method && _user)) {
00236 LM_ERR("invalid parameter value\n");
00237 return -1;
00238 }
00239
00240 method = *_method;
00241 user = *_user;
00242
00243
00244
00245
00246
00247 if (_cred->username.domain.len) {
00248 if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, _cred->username.whole.s, _cred->username.whole.len, 0)) {
00249 LM_ERR("unable to add User-Name attribute\n");
00250 goto err;
00251 }
00252 } else {
00253 user_name.len = _cred->username.user.len + _cred->realm.len + 1;
00254 user_name.s = pkg_malloc(user_name.len);
00255 if (!user_name.s) {
00256 LM_ERR("no pkg memory left\n");
00257 return -3;
00258 }
00259 memcpy(user_name.s, _cred->username.whole.s, _cred->username.whole.len);
00260 user_name.s[_cred->username.whole.len] = '@';
00261 memcpy(user_name.s + _cred->username.whole.len + 1, _cred->realm.s,
00262 _cred->realm.len);
00263 if (!rc_avpair_add(rh, &send, attrs[A_USER_NAME].v, user_name.s,
00264 user_name.len, 0)) {
00265 LM_ERR("unable to add User-Name attribute\n");
00266 pkg_free(user_name.s);
00267 goto err;
00268 }
00269 pkg_free(user_name.s);
00270 }
00271
00272 if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_USER_NAME].v,
00273 _cred->username.whole.s, _cred->username.whole.len, 0)) {
00274 LM_ERR("unable to add Digest-User-Name attribute\n");
00275 goto err;
00276 }
00277
00278 if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_REALM].v, _cred->realm.s,
00279 _cred->realm.len, 0)) {
00280 LM_ERR("unable to add Digest-Realm attribute\n");
00281 goto err;
00282 }
00283 if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_NONCE].v, _cred->nonce.s,
00284 _cred->nonce.len, 0)) {
00285 LM_ERR("unable to add Digest-Nonce attribute\n");
00286 goto err;
00287 }
00288
00289 if (use_ruri_flag < 0 || isflagset(_msg, use_ruri_flag) != 1) {
00290 ruri = &_cred->uri;
00291 } else {
00292 ruri = GET_RURI(_msg);
00293 }
00294 if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_URI].v, ruri->s,
00295 ruri->len, 0)) {
00296 LM_ERR("unable to add Digest-URI attribute\n");
00297 goto err;
00298 }
00299
00300 if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_METHOD].v, method.s,
00301 method.len, 0)) {
00302 LM_ERR("unable to add Digest-Method attribute\n");
00303 goto err;
00304 }
00305
00306
00307
00308
00309 if (_cred->qop.qop_parsed == QOP_AUTH) {
00310 if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_QOP].v, "auth", 4, 0)) {
00311 LM_ERR("unable to add Digest-QOP attribute\n");
00312 goto err;
00313 }
00314 if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_NONCE_COUNT].v,
00315 _cred->nc.s, _cred->nc.len, 0)) {
00316 LM_ERR("unable to add Digest-CNonce-Count attribute\n");
00317 goto err;
00318 }
00319 if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_CNONCE].v,
00320 _cred->cnonce.s, _cred->cnonce.len, 0)) {
00321 LM_ERR("unable to add Digest-CNonce attribute\n");
00322 goto err;
00323 }
00324 } else if (_cred->qop.qop_parsed == QOP_AUTHINT) {
00325 if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_QOP].v,
00326 "auth-int", 8, 0)) {
00327 LM_ERR("unable to add Digest-QOP attribute\n");
00328 goto err;
00329 }
00330 if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_NONCE_COUNT].v,
00331 _cred->nc.s, _cred->nc.len, 0)) {
00332 LM_ERR("unable to add Digest-Nonce-Count attribute\n");
00333 goto err;
00334 }
00335 if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_CNONCE].v,
00336 _cred->cnonce.s, _cred->cnonce.len, 0)) {
00337 LM_ERR("unable to add Digest-CNonce attribute\n");
00338 goto err;
00339 }
00340 if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_BODY_DIGEST].v,
00341 _cred->opaque.s, _cred->opaque.len, 0)) {
00342 LM_ERR("unable to add Digest-Body-Digest attribute\n");
00343 goto err;
00344 }
00345
00346 } else {
00347
00348 }
00349
00350
00351 if (!rc_avpair_add(rh, &send, attrs[A_DIGEST_RESPONSE].v,
00352 _cred->response.s, _cred->response.len, 0)) {
00353 LM_ERR("unable to add Digest-Response attribute\n");
00354 goto err;
00355 }
00356
00357
00358 service = vals[V_SIP_SESSION].v;
00359 if (!rc_avpair_add(rh, &send, attrs[A_SERVICE_TYPE].v, &service, -1, 0)) {
00360 LM_ERR("unable to add Service-Type attribute\n");
00361 goto err;
00362 }
00363
00364
00365 if (!rc_avpair_add(rh,&send,attrs[A_SIP_URI_USER].v,user.s,user.len,0)) {
00366 LM_ERR("unable to add Sip-URI-User attribute\n");
00367 goto err;
00368 }
00369
00370 if (attrs[A_CISCO_AVPAIR].n != NULL) {
00371 if (add_cisco_vsa(&send, _msg)) {
00372 goto err;
00373 }
00374 }
00375
00376
00377 extra_cnt = extra2strar(auth_extra, _msg, val_arr);
00378 if (extra_cnt == -1) {
00379 LM_ERR("in getting values of extra attributes\n");
00380 goto err;
00381 }
00382 offset = A_MAX;
00383 for (i = 0; i < extra_cnt; i++) {
00384 if (val_arr[i].len == -1) {
00385
00386 ADD_EXTRA_AVPAIR(attrs, offset+i,
00387 &(val_arr[i].s), val_arr[i].len );
00388 } else {
00389
00390 ADD_EXTRA_AVPAIR(attrs, offset+i,
00391 val_arr[i].s, val_arr[i].len );
00392 }
00393 }
00394
00395
00396 if ((i = rc_auth(rh, SIP_PORT, send, &received, msg)) == OK_RC) {
00397 LM_DBG("Success\n");
00398 rc_avpair_free(send);
00399 send = 0;
00400
00401 generate_avps(received);
00402
00403 rc_avpair_free(received);
00404 return 1;
00405 } else {
00406 #ifdef REJECT_RC
00407 if (i == REJECT_RC) {
00408 LM_DBG("Failure\n");
00409 goto err;
00410 }
00411 #endif
00412 LM_ERR("authorization failed\n");
00413 }
00414
00415 err:
00416 if (send) rc_avpair_free(send);
00417 if (received) rc_avpair_free(received);
00418 return -1;
00419 }