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
00034
00035 #include <string.h>
00036 #include <stdlib.h>
00037 #include "../../mem/mem.h"
00038 #include "../../str.h"
00039 #include "../../sr_module.h"
00040 #include "../../parser/hf.h"
00041 #include "../../parser/digest/digest.h"
00042 #include "../../parser/parse_uri.h"
00043 #include "../../parser/parse_from.h"
00044 #include "../../parser/parse_to.h"
00045 #include "../../dprint.h"
00046 #include "../../id.h"
00047 #include "../../ut.h"
00048 #include "../auth/api.h"
00049 #include "authorize.h"
00050 #include "sterman.h"
00051 #include "authrad_mod.h"
00052
00053
00054 static void attr_name_value(str* name, str* value, VALUE_PAIR* vp)
00055 {
00056 int i;
00057
00058 for (i = 0; i < vp->lvalue; i++) {
00059 if (vp->strvalue[i] == ':' || vp->strvalue[i] == '=') {
00060 name->s = vp->strvalue;
00061 name->len = i;
00062
00063 if (i == (vp->lvalue - 1)) {
00064 value->s = (char*)0;
00065 value->len = 0;
00066 } else {
00067 value->s = vp->strvalue + i + 1;
00068 value->len = vp->lvalue - i - 1;
00069 }
00070 return;
00071 }
00072 }
00073
00074 name->len = value->len = 0;
00075 name->s = value->s = (char*)0;
00076 }
00077
00078
00079
00080
00081
00082 static int generate_avps(VALUE_PAIR* received)
00083 {
00084 int_str name, val;
00085 VALUE_PAIR *vp;
00086
00087 vp = rc_avpair_get(received, ATTRID(attrs[A_SER_UID].v), VENDOR(attrs[A_SER_UID].v));
00088 if (vp == NULL) {
00089 WARN("RADIUS server did not send SER-UID attribute in digest authentication reply\n");
00090 return -1;
00091 }
00092 val.s.len = vp->lvalue;
00093 val.s.s = vp->strvalue;
00094 name.s.s = "uid";
00095 name.s.len = 3;
00096
00097 if (add_avp(AVP_TRACK_FROM | AVP_CLASS_USER | AVP_NAME_STR | AVP_VAL_STR, name, val) < 0) {
00098 ERR("Unable to create UID attribute\n");
00099 return -1;
00100 }
00101
00102 vp = received;
00103 while ((vp = rc_avpair_get(vp, ATTRID(attrs[A_SER_ATTR].v), VENDOR(attrs[A_SER_ATTR].v)))) {
00104 attr_name_value(&name.s, &val.s, vp);
00105 if (name.s.len == 0) {
00106 ERR("Missing attribute name\n");
00107 return -1;
00108 }
00109
00110 if (add_avp(AVP_TRACK_FROM | AVP_CLASS_USER | AVP_NAME_STR | AVP_VAL_STR, name, val) < 0) {
00111 LOG(L_ERR, "generate_avps: Unable to create a new AVP\n");
00112 return -1;
00113 } else {
00114 DBG("generate_avps: AVP '%.*s'='%.*s' has been added\n",
00115 name.s.len, ZSW(name.s.s),
00116 val.s.len, ZSW(val.s.s));
00117 }
00118 vp = vp->next;
00119 }
00120
00121 return 0;
00122 }
00123
00124
00125
00126
00127
00128
00129
00130 static inline int get_uri(struct sip_msg* _m, str** _uri)
00131 {
00132 if ((REQ_LINE(_m).method.len == 8) && (memcmp(REQ_LINE(_m).method.s, "REGISTER", 8) == 0)) {
00133 if (!_m->to && ((parse_headers(_m, HDR_TO_F, 0) == -1) || !_m->to)) {
00134 LOG(L_ERR, "get_uri(): To header field not found or malformed\n");
00135 return -1;
00136 }
00137 *_uri = &(get_to(_m)->uri);
00138 } else {
00139 if (parse_from_header(_m) == -1) {
00140 LOG(L_ERR, "get_uri(): Error while parsing headers\n");
00141 return -2;
00142 }
00143 *_uri = &(get_from(_m)->uri);
00144 }
00145 return 0;
00146 }
00147
00148
00149
00150
00151
00152 static inline int authenticate(struct sip_msg* msg, str* realm,
00153 hdr_types_t hftype)
00154 {
00155 int res;
00156 auth_result_t ret;
00157 struct hdr_field* h;
00158 auth_body_t* cred;
00159 str* uri;
00160 struct sip_uri puri;
00161 str user, did;
00162 VALUE_PAIR* received;
00163
00164 cred = 0;
00165 ret = -1;
00166 user.s = 0;
00167 received = NULL;
00168
00169 switch(auth_api.pre_auth(msg, realm, hftype, &h, NULL)) {
00170 default:
00171 BUG("unexpected reply '%d'.\n", auth_api.pre_auth(msg, realm, hftype,
00172 &h, NULL));
00173 #ifdef EXTRA_DEBUG
00174 abort();
00175 #endif
00176 case ERROR:
00177 case BAD_CREDENTIALS:
00178 ret = -3;
00179 goto end;
00180
00181 case NOT_AUTHENTICATED:
00182 ret = -1;
00183 goto end;
00184
00185 case DO_AUTHENTICATION:
00186 break;
00187
00188 case AUTHENTICATED:
00189 ret = 1;
00190 goto end;
00191 }
00192
00193 cred = (auth_body_t*)h->parsed;
00194
00195 if (use_did) {
00196 if (msg->REQ_METHOD == METHOD_REGISTER) {
00197 ret = get_to_did(&did, msg);
00198 } else {
00199 ret = get_from_did(&did, msg);
00200 }
00201 if (ret == 0) {
00202 did.s = DEFAULT_DID;
00203 did.len = sizeof(DEFAULT_DID) - 1;
00204 }
00205 } else {
00206 did.len = 0;
00207 did.s = 0;
00208 }
00209
00210 if (get_uri(msg, &uri) < 0) {
00211 LOG(L_ERR, "authorize(): From/To URI not found\n");
00212 ret = -1;
00213 goto end;
00214 }
00215
00216 if (parse_uri(uri->s, uri->len, &puri) < 0) {
00217 LOG(L_ERR, "authorize(): Error while parsing From/To URI\n");
00218 ret = -1;
00219 goto end;
00220 }
00221
00222 user.s = (char *)pkg_malloc(puri.user.len);
00223 if (user.s == NULL) {
00224 LOG(L_ERR, "authorize: No memory left\n");
00225 ret = -1;
00226 goto end;
00227 }
00228 un_escape(&(puri.user), &user);
00229
00230 res = radius_authorize_sterman(&received, msg, &cred->digest, &msg->first_line.u.request.method, &user);
00231 if (res == 1) {
00232 switch(auth_api.post_auth(msg, h)) {
00233 case ERROR:
00234 case BAD_CREDENTIALS:
00235 ret = -2;
00236 break;
00237
00238 case NOT_AUTHENTICATED:
00239 ret = -1;
00240 break;
00241
00242 case AUTHENTICATED:
00243 if (generate_avps(received) < 0) {
00244 ret = -1;
00245 break;
00246 }
00247 ret = 1;
00248 break;
00249
00250 default:
00251 ret = -1;
00252 break;
00253 }
00254 } else {
00255 ret = -1;
00256 }
00257
00258 end:
00259 if (received) rc_avpair_free(received);
00260 if (user.s) pkg_free(user.s);
00261 if (ret < 0) {
00262 if (auth_api.build_challenge(msg, (cred ? cred->stale : 0), realm, NULL, NULL, hftype) < 0) {
00263 ERR("Error while creating challenge\n");
00264 ret = -2;
00265 }
00266 }
00267 return ret;
00268 }
00269
00270
00271
00272
00273
00274 int radius_proxy_authorize(struct sip_msg* _msg, char* p1, char* p2)
00275 {
00276 str realm;
00277
00278 if (get_str_fparam(&realm, _msg, (fparam_t*)p1) < 0) {
00279 ERR("Cannot obtain digest realm from parameter '%s'\n", ((fparam_t*)p1)->orig);
00280 return -1;
00281 }
00282
00283
00284 return authenticate(_msg, &realm, HDR_PROXYAUTH_T);
00285 }
00286
00287
00288
00289
00290
00291 int radius_www_authorize(struct sip_msg* _msg, char* p1, char* p2)
00292 {
00293 str realm;
00294
00295 if (get_str_fparam(&realm, _msg, (fparam_t*)p1) < 0) {
00296 ERR("Cannot obtain digest realm from parameter '%s'\n", ((fparam_t*)p1)->orig);
00297 return -1;
00298 }
00299
00300 return authenticate(_msg, &realm, HDR_AUTHORIZATION_T);
00301 }
00302