/** * TODO move it to rfc2617.c * * @param auth_res return value of authentication. Maybe the it will be not affected. * @result if authentication should continue (1) or not (0) * */ static int auth_check_hdr_md5(struct sip_msg* msg, auth_body_t* auth, auth_result_t* auth_res) { int ret; /* Check credentials correctness here */ if (check_dig_cred(&auth->digest) != E_DIG_OK) { LOG(L_ERR, "auth:pre_auth: Credentials are not filled properly\n"); *auth_res = BAD_CREDENTIALS; return 0; } ret = check_nonce(auth, &secret1, &secret2, msg); if (ret!=0){ if (ret==3 || ret==4){ /* failed auth_extra_checks or stale */ auth->stale=1; /* we mark the nonce as stale (hack that makes our life much easier) */ *auth_res = STALE_NONCE; return 0; } else if (ret==6) { *auth_res = NONCE_REUSED; return 0; } else { DBG("auth:pre_auth: Invalid nonce value received (ret %d)\n", ret); *auth_res = NOT_AUTHENTICATED; return 0; } } return 1; }
/* * Purpose of this function is to find credentials with given realm, * do sanity check, validate credential correctness and determine if * we should really authenticate (there must be no authentication for * ACK and CANCEL */ auth_result_t pre_auth(struct sip_msg* _m, str* _realm, int _hftype, struct hdr_field** _h) { int ret; auth_body_t* c; struct sip_uri uri; /* ACK and CANCEL must be always authorized, there is * no way how to challenge ACK and CANCEL cannot be * challenged because it must have the same CSeq as * the request to be cancelled */ if ((_m->REQ_METHOD == METHOD_ACK) || (_m->REQ_METHOD == METHOD_CANCEL)) return AUTHORIZED; if (_realm->len == 0) { if (get_realm(_m, _hftype, &uri) < 0) { LOG(L_ERR, "pre_auth(): Error while extracting realm\n"); if (send_resp(_m, 400, MESSAGE_400, 0, 0) == -1) { LOG(L_ERR, "pre_auth(): Error while sending 400 reply\n"); } return ERROR; } *_realm = uri.host; strip_realm(_realm); } /* Try to find credentials with corresponding realm * in the message, parse them and return pointer to * parsed structure */ ret = find_credentials(_m, _realm, _hftype, _h); if (ret < 0) { LOG(L_ERR, "pre_auth(): Error while looking for credentials\n"); if (send_resp(_m, (ret == -2) ? 500 : 400, (ret == -2) ? MESSAGE_500 : MESSAGE_400, 0, 0) == -1) { LOG(L_ERR, "pre_auth(): Error while sending 400 reply\n"); } return ERROR; } else if (ret > 0) { DBG("pre_auth(): Credentials with given realm not found\n"); return NOT_AUTHORIZED; } /* Pointer to the parsed credentials */ c = (auth_body_t*)((*_h)->parsed); /* Check credentials correctness here */ if (check_dig_cred(&(c->digest)) != E_DIG_OK) { LOG(L_ERR, "pre_auth(): Credentials received are not filled properly\n"); if (send_resp(_m, 400, MESSAGE_400, 0, 0) == -1) { LOG(L_ERR, "pre_auth(): Error while sending 400 reply\n"); } return ERROR; } if (check_nonce(&c->digest.nonce, &secret) != 0) { DBG("pre_auth(): Invalid nonce value received\n"); return NOT_AUTHORIZED; } return DO_AUTHORIZATION; }
/* * Purpose of this function is to find credentials with given realm, * do sanity check, validate credential correctness and determine if * we should really authenticate (there must be no authentication for * ACK and CANCEL */ auth_result_t pre_auth(struct sip_msg* _m, str* _realm, hdr_types_t _hftype, struct hdr_field** _h) { int ret; auth_body_t* c; struct sip_uri *uri; /* ACK and CANCEL must be always authorized, there is * no way how to challenge ACK and CANCEL cannot be * challenged because it must have the same CSeq as * the request to be canceled */ if ((_m->REQ_METHOD == METHOD_ACK) || (_m->REQ_METHOD == METHOD_CANCEL)) return AUTHORIZED; if (_realm->len == 0) { if (get_realm(_m, _hftype, &uri) < 0) { LM_ERR("failed to extract realm\n"); if (send_resp(_m, 400, &auth_400_err, 0, 0) == -1) { LM_ERR("failed to send 400 reply\n"); } return ERROR; } *_realm = uri->host; strip_realm(_realm); } /* Try to find credentials with corresponding realm * in the message, parse them and return pointer to * parsed structure */ ret = find_credentials(_m, _realm, _hftype, _h); if (ret < 0) { LM_ERR("failed to find credentials\n"); if (send_resp(_m, (ret == -2) ? 500 : 400, (ret == -2) ? &auth_500_err : &auth_400_err, 0, 0) == -1) { LM_ERR("failed to send 400 reply\n"); } return ERROR; } else if (ret > 0) { LM_DBG("credentials with given realm not found\n"); return NO_CREDENTIALS; } /* Pointer to the parsed credentials */ c = (auth_body_t*)((*_h)->parsed); /* Check credentials correctness here */ if (check_dig_cred(&(c->digest)) != E_DIG_OK) { LM_DBG("received credentials are not filled properly\n"); if (send_resp(_m, 400, &auth_400_err, 0, 0) == -1) { LM_ERR("failed to send 400 reply\n"); } return ERROR; } if (mark_authorized_cred(_m, *_h) < 0) { LM_ERR("failed to mark parsed credentials\n"); if (send_resp(_m, 500, &auth_400_err, 0, 0) == -1) { LM_ERR("failed to send 400 reply\n"); } return ERROR; } if (is_nonce_stale(&c->digest.nonce)) { LM_DBG("stale nonce value received\n"); c->stale = 1; return STALE_NONCE; } if (check_nonce(&c->digest.nonce, &secret) != 0) { LM_DBG("invalid nonce value received\n"); c->stale = 1; return STALE_NONCE; } return DO_AUTHORIZATION; }