static inline int do_auth(struct sip_msg *_m, struct hdr_field *_h, str *_realm, str *_method, str *_secret) { auth_result_t ret; char ha1[512]; auth_body_t *cred = (auth_body_t*) _h->parsed; LM_DBG("secret: %.*s (%i)\n", _secret->len, _secret->s, _secret->len); if (get_ha1(&cred->digest.username, _realm, _secret, ha1) < 0) { LM_ERR("calculating HA1\n"); return AUTH_ERROR; } LM_DBG("HA1: %i\n", (int)strlen(ha1)); ret = eph_auth_api.check_response(&cred->digest, _method, ha1); if (ret == AUTHENTICATED) { if (eph_auth_api.post_auth(_m, _h, ha1) != AUTHENTICATED) { return AUTH_ERROR; } return AUTH_OK; } else if (ret == NOT_AUTHENTICATED) { return AUTH_INVALID_PASSWORD; } else { return AUTH_ERROR; } }
/* * Authorize digest credentials */ static inline int digest_authenticate(struct sip_msg* msg, fparam_t* realm, char* tname, hdr_types_t hftype) { char ha1[256]; int res; struct hdr_field* h; auth_body_t* cred; str domain, table; db1_res_t* result = NULL; int ret; cred = 0; ret = AUTH_ERROR; if(!tname) { LM_ERR("invalid table parameter\n"); return AUTH_ERROR; } table.s = tname; table.len = strlen(tname); if (get_str_fparam(&domain, msg, realm) < 0) { LM_ERR("failed to get realm value\n"); goto end; } if (domain.len==0) { LM_ERR("invalid realm parameter - empty value\n"); goto end; } LM_DBG("realm value [%.*s]\n", domain.len, domain.s); ret = auth_api.pre_auth(msg, &domain, hftype, &h, NULL); switch(ret) { case ERROR: case BAD_CREDENTIALS: LM_DBG("error or bad credentials\n"); ret = AUTH_ERROR; goto end; case CREATE_CHALLENGE: LM_ERR("CREATE_CHALLENGE is not a valid state\n"); ret = AUTH_ERROR; goto end; case DO_RESYNCHRONIZATION: LM_ERR("DO_RESYNCHRONIZATION is not a valid state\n"); ret = AUTH_ERROR; goto end; case NOT_AUTHENTICATED: LM_DBG("not authenticated\n"); ret = AUTH_ERROR; goto end; case DO_AUTHENTICATION: break; case AUTHENTICATED: ret = AUTH_OK; goto end; } cred = (auth_body_t*)h->parsed; res = get_ha1(&cred->digest.username, &domain, &table, ha1, &result); if (res < 0) { /* Error while accessing the database */ ret = AUTH_ERROR; goto end; } if (res > 0) { /* Username not found in the database */ ret = AUTH_USER_UNKNOWN; goto end; } /* Recalculate response, it must be same to authorize successfully */ ret = auth_api.check_response(&(cred->digest), &msg->first_line.u.request.method, ha1); if(ret==AUTHENTICATED) { ret = AUTH_OK; switch(auth_api.post_auth(msg, h)) { case AUTHENTICATED: generate_avps(result); break; default: ret = AUTH_ERROR; break; } } else { if(ret==NOT_AUTHENTICATED) ret = AUTH_INVALID_PASSWORD; else ret = AUTH_ERROR; } end: if(result) auth_dbf.free_result(auth_db_handle, result); return ret; }
/* * Authorize digest credentials and set the pointer to used hdr */ static int digest_authenticate_hdr(sip_msg_t* msg, str *realm, str *table, hdr_types_t hftype, str *method, hdr_field_t **ahdr) { char ha1[256]; int res; struct hdr_field* h; auth_body_t* cred; db1_res_t* result = NULL; int ret; cred = 0; ret = AUTH_ERROR; ret = auth_api.pre_auth(msg, realm, hftype, &h, NULL); switch(ret) { case NONCE_REUSED: LM_DBG("nonce reused"); ret = AUTH_NONCE_REUSED; goto end; case STALE_NONCE: LM_DBG("stale nonce\n"); ret = AUTH_STALE_NONCE; goto end; case NO_CREDENTIALS: LM_DBG("no credentials\n"); ret = AUTH_NO_CREDENTIALS; goto end; case ERROR: case BAD_CREDENTIALS: LM_DBG("error or bad credentials\n"); ret = AUTH_ERROR; goto end; case CREATE_CHALLENGE: LM_ERR("CREATE_CHALLENGE is not a valid state\n"); ret = AUTH_ERROR; goto end; case DO_RESYNCHRONIZATION: LM_ERR("DO_RESYNCHRONIZATION is not a valid state\n"); ret = AUTH_ERROR; goto end; case NOT_AUTHENTICATED: LM_DBG("not authenticated\n"); ret = AUTH_ERROR; goto end; case DO_AUTHENTICATION: break; case AUTHENTICATED: ret = AUTH_OK; goto end; } cred = (auth_body_t*)h->parsed; if(ahdr!=NULL) *ahdr = h; res = get_ha1(&cred->digest.username, realm, table, ha1, &result); if (res < 0) { /* Error while accessing the database */ ret = AUTH_ERROR; goto end; } if (res > 0) { /* Username not found in the database */ ret = AUTH_USER_UNKNOWN; goto end; } /* Recalculate response, it must be same to authorize successfully */ ret = auth_api.check_response(&(cred->digest), method, ha1); if(ret==AUTHENTICATED) { ret = AUTH_OK; switch(auth_api.post_auth(msg, h, ha1)) { case AUTHENTICATED: generate_avps(msg, result); break; default: ret = AUTH_ERROR; break; } } else { if(ret==NOT_AUTHENTICATED) ret = AUTH_INVALID_PASSWORD; else ret = AUTH_ERROR; } end: if(result) auth_dbf.free_result(auth_db_handle, result); return ret; }
/* * Authorize digest credentials */ static inline int authorize(struct sip_msg* _m, str* _realm, char* _table, hdr_types_t _hftype) { char ha1[256]; int res; struct hdr_field* h; auth_body_t* cred; auth_result_t ret; str domain; db_res_t* result; domain = *_realm; ret = auth_api.pre_auth(_m, &domain, _hftype, &h); switch(ret) { case ERROR: return 0; case NOT_AUTHORIZED: return -1; case DO_AUTHORIZATION: break; case AUTHORIZED: return 1; } cred = (auth_body_t*)h->parsed; res = get_ha1(&cred->digest.username, &domain, _table, ha1, &result); if (res < 0) { /* Error while accessing the database */ if (sl_reply(_m, (char*)500, MESSAGE_500) == -1) { LOG(L_ERR, "authorize(): Error while sending 500 reply\n"); } return 0; } if (res > 0) { /* Username not found in the database */ auth_dbf.free_result(auth_db_handle, result); return -1; } /* Recalculate response, it must be same to authorize successfully */ if (!check_response(&(cred->digest),&_m->first_line.u.request.method,ha1)) { ret = auth_api.post_auth(_m, h); switch(ret) { case ERROR: auth_dbf.free_result(auth_db_handle, result); return 1; case NOT_AUTHORIZED: auth_dbf.free_result(auth_db_handle, result); return -1; case AUTHORIZED: generate_avps(result); auth_dbf.free_result(auth_db_handle, result); return 1; default: auth_dbf.free_result(auth_db_handle, result); return -1; } } auth_dbf.free_result(auth_db_handle, result); return -1; }
/* * Authorize digest credentials */ static inline int authorize(struct sip_msg* _m, gparam_p _realm, char* _table, hdr_types_t _hftype) { char ha1[256]; int res; struct hdr_field* h; auth_body_t* cred; auth_result_t ret; str domain, table; db_res_t* result = NULL; if(!_table) { LM_ERR("invalid table parameter\n"); return -1; } table.s = _table; table.len = strlen(_table); if(fixup_get_svalue(_m, _realm, &domain)!=0) { LM_ERR("invalid realm parameter\n"); return AUTH_ERROR; } if (domain.len==0) domain.s = 0; ret = auth_api.pre_auth(_m, &domain, _hftype, &h); if (ret != DO_AUTHORIZATION) return ret; cred = (auth_body_t*)h->parsed; res = get_ha1(&cred->digest.username, &domain, &table, ha1, &result); if (res < 0) { /* Error while accessing the database */ if (sigb.reply(_m, 500, &auth_500_err, NULL) == -1) { LM_ERR("failed to send 500 reply\n"); } return ERROR; } if (res > 0) { /* Username not found in the database */ auth_dbf.free_result(auth_db_handle, result); return USER_UNKNOWN; } /* Recalculate response, it must be same to authorize successfully */ if (!auth_api.check_response(&(cred->digest), &_m->first_line.u.request.method, ha1)) { ret = auth_api.post_auth(_m, h); if (ret == AUTHORIZED) generate_avps(result); auth_dbf.free_result(auth_db_handle, result); return ret; } auth_dbf.free_result(auth_db_handle, result); return INVALID_PASSWORD; }
/* * Authenticate digest credentials * Returns: * -3 -- Bad Request * -2 -- Error while checking credentials (such as malformed message or database problem) * -1 -- Authentication failed * 1 -- Authentication successful */ static inline int authenticate(struct sip_msg* msg, str* realm, authdb_table_info_t *table, hdr_types_t hftype) { char ha1[256]; int res, ret; db_rec_t *row; struct hdr_field* h; auth_body_t* cred; db_res_t* result; str did; cred = 0; result = 0; ret = -1; switch(auth_api.pre_auth(msg, realm, hftype, &h, NULL)) { case ERROR: case BAD_CREDENTIALS: ret = -3; goto end; case CREATE_CHALLENGE: ERR("auth_db:authenticate: CREATE_CHALLENGE is not a valid state\n"); ret = -2; goto end; case DO_RESYNCHRONIZATION: ERR("auth_db:authenticate: DO_RESYNCHRONIZATION is not a valid state\n"); ret = -2; goto end; case NOT_AUTHENTICATED: ret = -1; goto end; case DO_AUTHENTICATION: break; case AUTHENTICATED: ret = 1; goto end; } cred = (auth_body_t*)h->parsed; if (use_did) { if (msg->REQ_METHOD == METHOD_REGISTER) { ret = get_to_did(&did, msg); } else { ret = get_from_did(&did, msg); } if (ret == 0) { did.s = DEFAULT_DID; did.len = sizeof(DEFAULT_DID) - 1; } } else { did.len = 0; did.s = 0; } if (check_all) { res = check_all_ha1(msg, h, &(cred->digest), &msg->first_line.u.request.method, &did, realm, table, &result); if (res < 0) { ret = -2; goto end; } else if (res > 0) { ret = -1; goto end; } else { ret = 1; goto end; } } else { res = get_ha1(&cred->digest.username, &did, realm, table, ha1, &result, &row); if (res < 0) { ret = -2; goto end; } if (res > 0) { /* Username not found in the database */ ret = -1; goto end; } } /* Recalculate response, it must be same to authorize successfully */ if (!check_response(&(cred->digest), &msg->first_line.u.request.method, ha1)) { switch(auth_api.post_auth(msg, h)) { case ERROR: case BAD_CREDENTIALS: ret = -2; break; case NOT_AUTHENTICATED: ret = -1; break; case AUTHENTICATED: generate_avps(result, row); ret = 1; break; default: ret = -1; break; } } else { ret = -1; } end: if (result) db_res_free(result); if (ret < 0) { if (auth_api.build_challenge(msg, (cred ? cred->stale : 0), realm, NULL, NULL, hftype) < 0) { ERR("Error while creating challenge\n"); ret = -2; } } return ret; }