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 #include <string.h>
00031 #include "../../dprint.h"
00032 #include "../../parser/digest/digest.h"
00033 #include "../../sr_module.h"
00034 #include "../../str.h"
00035 #include "../../ut.h"
00036 #include "auth_mod.h"
00037 #include "nonce.h"
00038 #include "common.h"
00039 #include "api.h"
00040 #include "rpid.h"
00041 #include "index.h"
00042
00043 static str auth_400_err = str_init(MESSAGE_400);
00044 static str auth_500_err = str_init(MESSAGE_500);
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 void strip_realm(str* _realm)
00055 {
00056
00057 if (!realm_prefix.len) return;
00058
00059
00060 if (realm_prefix.len > _realm->len) return;
00061
00062
00063 if (memcmp(realm_prefix.s, _realm->s, realm_prefix.len) == 0) {
00064 _realm->s += realm_prefix.len;
00065 _realm->len -= realm_prefix.len;
00066 }
00067 return;
00068 }
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 static inline int find_credentials(struct sip_msg* _m, str* _realm,
00079 hdr_types_t _hftype, struct hdr_field** _h)
00080 {
00081 struct hdr_field** hook, *ptr, *prev;
00082 hdr_flags_t hdr_flags;
00083 int res;
00084 str* r;
00085
00086
00087
00088
00089
00090
00091 switch(_hftype) {
00092 case HDR_AUTHORIZATION_T:
00093 hook = &(_m->authorization);
00094 hdr_flags=HDR_AUTHORIZATION_F;
00095 break;
00096 case HDR_PROXYAUTH_T:
00097 hook = &(_m->proxy_auth);
00098 hdr_flags=HDR_PROXYAUTH_F;
00099 break;
00100 default:
00101 hook = &(_m->authorization);
00102 hdr_flags=HDR_T2F(_hftype);
00103 break;
00104 }
00105
00106
00107
00108
00109 if (*hook == 0) {
00110
00111 if (parse_headers(_m, hdr_flags, 0) == -1) {
00112 LM_ERR("failed to parse headers\n");
00113 return -1;
00114 }
00115 }
00116
00117 ptr = *hook;
00118
00119
00120
00121
00122
00123 while(ptr) {
00124 res = parse_credentials(ptr);
00125 if (res < 0) {
00126 LM_ERR("failed to parse credentials\n");
00127 return (res == -1) ? -2 : -3;
00128 } else if (res == 0) {
00129 r = &(((auth_body_t*)(ptr->parsed))->digest.realm);
00130 if (r->len == _realm->len) {
00131 if (!strncasecmp(_realm->s, r->s, r->len)) {
00132 *_h = ptr;
00133 return 0;
00134 }
00135 }
00136 }
00137
00138 prev = ptr;
00139 if (parse_headers(_m, hdr_flags, 1) == -1) {
00140 LM_ERR("failed to parse headers\n");
00141 return -4;
00142 } else {
00143 if (prev != _m->last_header) {
00144 if (_m->last_header->type == _hftype) ptr = _m->last_header;
00145 else break;
00146 } else break;
00147 }
00148 }
00149
00150
00151
00152
00153
00154 return 1;
00155 }
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 auth_result_t pre_auth(struct sip_msg* _m, str* _realm, hdr_types_t _hftype,
00172 struct hdr_field** _h)
00173 {
00174 int ret;
00175 auth_body_t* c;
00176 struct sip_uri *uri;
00177
00178
00179
00180
00181
00182
00183
00184 if ((_m->REQ_METHOD == METHOD_ACK) || (_m->REQ_METHOD == METHOD_CANCEL))
00185 return AUTHORIZED;
00186
00187 if (_realm->len == 0) {
00188 if (get_realm(_m, _hftype, &uri) < 0) {
00189 LM_ERR("failed to extract realm\n");
00190 if (send_resp(_m, 400, &auth_400_err, 0, 0) == -1) {
00191 LM_ERR("failed to send 400 reply\n");
00192 }
00193 return ERROR;
00194 }
00195
00196 *_realm = uri->host;
00197 strip_realm(_realm);
00198 }
00199
00200
00201
00202
00203
00204 ret = find_credentials(_m, _realm, _hftype, _h);
00205 if (ret < 0) {
00206 LM_ERR("failed to find credentials\n");
00207 if (send_resp(_m, (ret == -2) ? 500 : 400,
00208 (ret == -2) ? &auth_500_err : &auth_400_err, 0, 0) == -1) {
00209 LM_ERR("failed to send 400 reply\n");
00210 }
00211 return ERROR;
00212 } else if (ret > 0) {
00213 LM_DBG("credentials with given realm not found\n");
00214 return NO_CREDENTIALS;
00215 }
00216
00217
00218 c = (auth_body_t*)((*_h)->parsed);
00219
00220
00221 if (check_dig_cred(&(c->digest)) != E_DIG_OK) {
00222 LM_ERR("received credentials are not filled properly\n");
00223 if (send_resp(_m, 400, &auth_400_err, 0, 0) == -1) {
00224 LM_ERR("failed to send 400 reply\n");
00225 }
00226 return ERROR;
00227 }
00228
00229 if (mark_authorized_cred(_m, *_h) < 0) {
00230 LM_ERR("failed to mark parsed credentials\n");
00231 if (send_resp(_m, 500, &auth_400_err, 0, 0) == -1) {
00232 LM_ERR("failed to send 400 reply\n");
00233 }
00234 return ERROR;
00235 }
00236
00237 if (check_nonce(&c->digest.nonce, &secret) != 0) {
00238 LM_DBG("invalid nonce value received\n");
00239 c->stale = 1;
00240 return STALE_NONCE;
00241 }
00242
00243 return DO_AUTHORIZATION;
00244 }
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 auth_result_t post_auth(struct sip_msg* _m, struct hdr_field* _h)
00257 {
00258 auth_body_t* c;
00259 int index = 0;
00260
00261 c = (auth_body_t*)((_h)->parsed);
00262
00263 if ((_m->REQ_METHOD == METHOD_ACK) ||
00264 (_m->REQ_METHOD == METHOD_CANCEL))
00265 return AUTHORIZED;
00266
00267 if (is_nonce_stale(&c->digest.nonce)) {
00268 LM_DBG("response is OK, but nonce is stale\n");
00269 c->stale = 1;
00270 return STALE_NONCE;
00271 } else {
00272 if(nonce_reuse==0)
00273 {
00274
00275 index= get_nonce_index(&c->digest.nonce);
00276 if(index== -1)
00277 {
00278 LM_ERR("failed to extract nonce index\n");
00279 return ERROR;
00280 }
00281 LM_DBG("nonce index= %d\n", index);
00282
00283 if(!is_nonce_index_valid(index))
00284 {
00285 LM_DBG("nonce index not valid\n");
00286 return NONCE_REUSED;
00287 }
00288 }
00289 }
00290 return AUTHORIZED;
00291 }
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304 int check_response(dig_cred_t* _cred, str* _method, char* _ha1)
00305 {
00306 HASHHEX resp, hent;
00307
00308
00309
00310
00311
00312 if (_cred->response.len != 32) {
00313 LM_DBG("receive response len != 32\n");
00314 return 1;
00315 }
00316
00317
00318
00319
00320
00321 calc_response(_ha1, &(_cred->nonce),
00322 &(_cred->nc), &(_cred->cnonce),
00323 &(_cred->qop.qop_str), _cred->qop.qop_parsed == QOP_AUTHINT,
00324 _method, &(_cred->uri), hent, resp);
00325
00326 LM_DBG("our result = \'%s\'\n", resp);
00327
00328
00329
00330
00331
00332 if (!memcmp(resp, _cred->response.s, 32)) {
00333 LM_DBG("authorization is OK\n");
00334 return 0;
00335 } else {
00336 LM_DBG("authorization failed\n");
00337 return 2;
00338 }
00339 }
00340
00341
00342
00343
00344
00345
00346
00347 int bind_auth(auth_api_t* api)
00348 {
00349 if (!api) {
00350 LM_ERR("invalid parameter value\n");
00351 return -1;
00352 }
00353
00354 api->pre_auth = pre_auth;
00355 api->post_auth = post_auth;
00356 api->calc_HA1 = calc_HA1;
00357 api->check_response = check_response;
00358
00359 get_rpid_avp( &api->rpid_avp, &api->rpid_avp_type );
00360
00361 return 0;
00362 }