/* Get called domain */ static str getToDomain(char** type, struct sip_msg* msg) { static char buf[16] = "unknown"; // buf is here for a reason. don't static str notfound = {buf, 7}; // use the constant string directly! static struct sip_uri puri; str uri, did; if (get_to_did(&did, msg) == 0) { *type = "local"; return did; } *type = "remote"; uri = get_to(msg)->uri; if (parse_uri(uri.s, uri.len, &puri) < 0) { LOG(L_ERR, "error: mediaproxy/getToDomain(): error parsing `To' URI\n"); return notfound; } else if (puri.host.len == 0) { return notfound; } return puri.host; }
// This function only works when called for a request although it's more // reliable than the getToDomain function. static str getDestinationDomain(char** type, struct sip_msg* msg) { static char buf[16] = "unknown"; // buf is here for a reason. don't static str notfound = {buf, 7}; // use the constant string directly! str did; if (get_to_did(&did, msg) == 0) { *type = "local"; return did; } *type = "remote"; if (parse_sip_msg_uri(msg) < 0) { LOG(L_ERR, "error: mediaproxy/getDestinationDomain(): error parsing destination URI\n"); return notfound; } else if (msg->parsed_uri.host.len==0) { return notfound; } return msg->parsed_uri.host; }
int sd_lookup(struct sip_msg* _msg, char* _index, char* _str2) { int i; str user_s, uid, did; db_res_t* res = NULL; db_rec_t* rec; /* init */ i = (int)(long)_index; /* Retrieve the owner of the record */ if (get_from_uid(&uid, _msg) < 0) { LOG(L_ERR, "sd_lookup: Unable to get user identity\n"); return -1; } /* Retrieve the called domain id */ if (get_to_did(&did, _msg) < 0) { LOG(L_ERR, "sd_lookup: Destination domain ID not known\n"); return -1; } tables[i].lookup_num->match[0].v.lstr = uid; tables[i].lookup_num->match[1].v.lstr = did; /* Get the called username */ if (parse_sip_msg_uri(_msg) < 0) { LOG(L_ERR, "sd_lookup: Error while parsing Request-URI\n"); goto err_badreq; } tables[i].lookup_num->match[2].v.lstr = _msg->parsed_uri.user; DBG("speeddial: Looking up (uid:%.*s,username:%.*s,did:%.*s)\n", uid.len, uid.s, _msg->parsed_uri.user.len, _msg->parsed_uri.user.s, did.len, did.s); if (db_exec(&res, tables[i].lookup_num) < 0) { ERR("speeddial: Error while executing database command\n"); goto err_server; } if (res == NULL) { DBG("speeddial: No SIP URI found for speeddial (num:%.*s, uid:%.*s," " did:%.*s)\n", _msg->parsed_uri.user.len, _msg->parsed_uri.user.s, uid.len, uid.s, did.len, did.s); return -1; } user_s.s = useruri_buf + 4; rec = db_first(res); while(rec) { if (rec->fld[0].flags & DB_NULL) goto skip; strncpy(user_s.s, rec->fld[0].v.lstr.s, rec->fld[0].v.lstr.len); user_s.len = rec->fld[0].v.lstr.len; user_s.s[user_s.len] = '\0'; goto out; skip: rec = db_next(res); } if (rec == NULL) { DBG("speeddial: No usable SIP URI found for (num:%.*s, uid:%.*s," " did:%.*s)\n", _msg->parsed_uri.user.len, _msg->parsed_uri.user.s, uid.len, uid.s, did.len, did.s); db_res_free(res); return -1; } out: /* check 'sip:' */ if(user_s.len<4 || strncmp(user_s.s, "sip:", 4)) { memcpy(useruri_buf, "sip:", 4); user_s.s -= 4; user_s.len += 4; } db_res_free(res); /* set the URI */ DBG("sd_lookup: URI of sd from R-URI [%s]\n", user_s.s); if(rewrite_uri(_msg, &user_s)<0) { LOG(L_ERR, "sd_lookup: Cannot replace the R-URI\n"); goto err_server; } return 1; err_server: if (slb.zreply(_msg, 500, "Server Internal Error") == -1) { LOG(L_ERR, "sd_lookup: Error while sending reply\n"); } return 0; err_badreq: if (slb.zreply(_msg, 400, "Bad Request") == -1) { LOG(L_ERR, "sd_lookup: Error while sending reply\n"); } return 0; }
/* * Authorize digest credentials */ static inline int authenticate(struct sip_msg* msg, str* realm, hdr_types_t hftype) { int res; auth_result_t ret; struct hdr_field* h; auth_body_t* cred; str* uri; struct sip_uri puri; str user, did; VALUE_PAIR* received; cred = 0; ret = -1; user.s = 0; received = NULL; switch(auth_api.pre_auth(msg, realm, hftype, &h, NULL)) { default: BUG("unexpected reply '%d'.\n", auth_api.pre_auth(msg, realm, hftype, &h, NULL)); #ifdef EXTRA_DEBUG abort(); #endif case ERROR: case BAD_CREDENTIALS: ret = -3; 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 (get_uri(msg, &uri) < 0) { LOG(L_ERR, "authorize(): From/To URI not found\n"); ret = -1; goto end; } if (parse_uri(uri->s, uri->len, &puri) < 0) { LOG(L_ERR, "authorize(): Error while parsing From/To URI\n"); ret = -1; goto end; } user.s = (char *)pkg_malloc(puri.user.len); if (user.s == NULL) { LOG(L_ERR, "authorize: No memory left\n"); ret = -1; goto end; } un_escape(&(puri.user), &user); res = radius_authorize_sterman(&received, msg, &cred->digest, &msg->first_line.u.request.method, &user); if (res == 1) { switch(auth_api.post_auth(msg, h)) { case ERROR: case BAD_CREDENTIALS: ret = -2; break; case NOT_AUTHENTICATED: ret = -1; break; case AUTHENTICATED: if (generate_avps(received) < 0) { ret = -1; break; } ret = 1; break; default: ret = -1; break; } } else { ret = -1; } end: if (received) rc_avpair_free(received); if (user.s) pkg_free(user.s); 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; }
/* * 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; }