Skip to content

Commit

Permalink
uri_db: rework the possibiltiy to use any sip uri (#1034)
Browse files Browse the repository at this point in the history
* uri_db: added subscriber and realm param to check_uri

* uri_db: fix whitespace bevor tab

* uri_db: last fix for log macros

* uri_db: removed change from log macros
  • Loading branch information
dunst0 authored and miconda committed Mar 27, 2017
1 parent d01141e commit fbe1ed2
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 60 deletions.
135 changes: 84 additions & 51 deletions src/modules/uri_db/checks.c
Expand Up @@ -15,8 +15,8 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
Expand All @@ -41,10 +41,12 @@ static db_func_t uridb_dbf;
* Check if a header field contains the same username
* as digest credentials
*/
static inline int check_username(struct sip_msg* _m, struct sip_uri *_uri)
static inline int check_username(struct sip_msg* _m, struct sip_uri *_uri,
str* _username, str* _realm)
{
struct hdr_field* h;
auth_body_t* c;
str username;
str realm;

db_key_t keys[3];
db_val_t vals[3];
db_key_t cols[1];
Expand All @@ -55,26 +57,38 @@ static inline int check_username(struct sip_msg* _m, struct sip_uri *_uri)
return -1;
}

/* Get authorized digest credentials */
get_authorized_cred(_m->authorization, &h);
if (!h) {
get_authorized_cred(_m->proxy_auth, &h);
if (!h) {
LM_ERR("No authorized credentials found (error in scripts)\n");
LM_ERR("Call {www,proxy}_authorize before calling check_* functions!\n");
return -2;
}
}

c = (auth_body_t*)(h->parsed);

/* Parse To/From URI */
/* Make sure that the URI contains username */
if (!_uri->user.len) {
LM_ERR("Username not found in URI\n");
return -4;
}

/* use digest credentials if no other credentials are supplied */
if (!_username || !_realm) {
struct hdr_field* h;
auth_body_t* c;

/* Get authorized digest credentials */
get_authorized_cred(_m->authorization, &h);
if (!h) {
get_authorized_cred(_m->proxy_auth, &h);
if (!h) {
LM_ERR("No authorized credentials found (error in scripts)\n");
LM_ERR("Call {www,proxy}_authorize before calling check_* functions!\n");
return -2;
}
}

c = (auth_body_t*)(h->parsed);

username = c->digest.username.user;
realm = *GET_REALM(&c->digest);
} else {
username = *_username;
realm = *_realm;
}

/* If use_uri_table is set, use URI table to determine if Digest username
* and To/From username match. URI table is a table enumerating all allowed
* usernames for a single, thus a user can have several different usernames
Expand All @@ -94,8 +108,8 @@ static inline int check_username(struct sip_msg* _m, struct sip_uri *_uri)
VAL_TYPE(vals) = VAL_TYPE(vals + 1) = VAL_TYPE(vals + 2) = DB1_STR;
VAL_NULL(vals) = VAL_NULL(vals + 1) = VAL_NULL(vals + 2) = 0;

VAL_STR(vals) = c->digest.username.user;
VAL_STR(vals + 1) = *GET_REALM(&c->digest);
VAL_STR(vals) = username;
VAL_STR(vals + 1) = realm;
VAL_STR(vals + 2) = _uri->user;

if (uridb_dbf.query(db_handle, keys, 0, vals, cols, 3, 1, 0, &res) < 0)
Expand All @@ -110,7 +124,7 @@ static inline int check_username(struct sip_msg* _m, struct sip_uri *_uri)
*/
if (RES_ROW_N(res) == 0) {
LM_DBG("From/To user '%.*s' is spoofed\n",
_uri->user.len, ZSW(_uri->user.s));
_uri->user.len, ZSW(_uri->user.s));
uridb_dbf.free_result(db_handle, res);
return -9;
} else {
Expand All @@ -123,9 +137,8 @@ static inline int check_username(struct sip_msg* _m, struct sip_uri *_uri)
/* URI table not used, simply compare digest username and From/To
* username, the comparison is case insensitive
*/
if (_uri->user.len == c->digest.username.user.len) {
if (!strncasecmp(_uri->user.s, c->digest.username.user.s,
_uri->user.len)) {
if (_uri->user.len == username.len) {
if (!strncasecmp(_uri->user.s, username.s, _uri->user.len)) {
LM_DBG("Digest username and URI username match\n");
return 1;
}
Expand All @@ -146,12 +159,12 @@ int check_to(struct sip_msg* _m, char* _s1, char* _s2)
LM_ERR("Error while parsing To header field\n");
return -1;
}
if(parse_to_uri(_m)==NULL) {
if (parse_to_uri(_m)==NULL) {
LM_ERR("Error while parsing To header URI\n");
return -1;
}

return check_username(_m, &get_to(_m)->parsed_uri);
return check_username(_m, &get_to(_m)->parsed_uri, NULL, NULL);
}


Expand All @@ -169,31 +182,51 @@ int check_from(struct sip_msg* _m, char* _s1, char* _s2)
return -1;
}

return check_username(_m, &get_from(_m)->parsed_uri);
return check_username(_m, &get_from(_m)->parsed_uri, NULL, NULL);
}


/*
*
* Checks username part of the supplied sip URI.
* Optinal with supplied credentials.
*/
int check_uri(struct sip_msg* msg, char* uri, char* _s2)
int check_uri(struct sip_msg* msg, char* uri, char* username, char* realm)
{
str suri;
struct sip_uri parsed_uri;

if (fixup_get_svalue(msg, (gparam_t*)uri, &suri) != 0)
{
ERR("cannot get uri value\n");
return -1;
}

if (parse_uri(suri.s, suri.len, &parsed_uri) != 0)
{
ERR("Error while parsing URI\n");
return -1;
}

return check_username(msg, &parsed_uri);
str suri;
str susername;
str srealm;

struct sip_uri parsed_uri;

if (get_str_fparam(&suri, msg, (fparam_t*) uri) != 0)
{
LM_ERR("Error while getting URI value\n");
return -1;
}

if (parse_uri(suri.s, suri.len, &parsed_uri) != 0)
{
LM_ERR("Error while parsing URI\n");
return -1;
}

if (!username || !realm) {
return check_username(msg, &parsed_uri, NULL, NULL);
}

if (get_str_fparam(&susername, msg, (fparam_t*) username) != 0)
{
LM_ERR("Error while getting username value\n");
return -1;
}

if (get_str_fparam(&srealm, msg, (fparam_t*) realm) != 0)
{
LM_ERR("Error while getting realm value\n");
return -1;
}

return check_username(msg, &parsed_uri, &susername, &srealm);
}


Expand Down Expand Up @@ -240,7 +273,7 @@ int does_uri_exist(struct sip_msg* _msg, char* _s1, char* _s2)
LM_ERR("Error while querying database\n");
return -4;
}

if (RES_ROW_N(res) == 0) {
LM_DBG("User in request uri does not exist\n");
uridb_dbf.free_result(db_handle, res);
Expand All @@ -257,10 +290,10 @@ int does_uri_exist(struct sip_msg* _msg, char* _s1, char* _s2)
int uridb_db_init(const str* db_url)
{
if (uridb_dbf.init==0){
LM_CRIT("BUG: null dbf\n");
return -1;
LM_BUG("null dbf\n");
return -1;
}

db_handle=uridb_dbf.init(db_url);
if (db_handle==0){
LM_ERR("unable to connect to the database\n");
Expand Down Expand Up @@ -300,9 +333,9 @@ int uridb_db_ver(const str* db_url, str* name)
{
db1_con_t* dbh;
int ver;

if (uridb_dbf.init==0){
LM_CRIT("BUG: unbound database\n");
LM_BUG("unbound database\n");
return -1;
}

Expand Down
9 changes: 5 additions & 4 deletions src/modules/uri_db/checks.h
Expand Up @@ -15,8 +15,8 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
Expand All @@ -43,9 +43,10 @@ int check_from(struct sip_msg* _msg, char* _str1, char* _str2);


/*
*
* Checks username part of the supplied sip URI.
* Optinal with supplied credentials.
*/
int check_uri(struct sip_msg* msg, char* uri, char* _s2);
int check_uri(struct sip_msg* msg, char* uri, char* username, char* realm);


/*
Expand Down
20 changes: 15 additions & 5 deletions src/modules/uri_db/uri_db.c
@@ -1,4 +1,4 @@
/*
/*
* Various URI related functions
*
* Copyright (C) 2001-2003 FhG Fokus
Expand All @@ -15,8 +15,8 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
Expand Down Expand Up @@ -71,6 +71,8 @@ int use_domain = 0; /* Should does_uri_exist honor the domain part ? */

static int fixup_exist(void** param, int param_no);

static int w_check_uri1(struct sip_msg* _m, char* _uri, char* _s);

/*
* Exported functions
*/
Expand All @@ -79,8 +81,10 @@ static cmd_export_t cmds[] = {
REQUEST_ROUTE},
{"check_from", (cmd_function)check_from, 0, 0, 0,
REQUEST_ROUTE},
{"check_uri", (cmd_function)check_uri, 1, fixup_spve_null, 0,
REQUEST_ROUTE},
{"check_uri", (cmd_function)w_check_uri1, 1, fixup_spve_null, 0,
REQUEST_ROUTE},
{"check_uri", (cmd_function)check_uri, 3, fixup_spve_all, 0,
REQUEST_ROUTE},
{"does_uri_exist", (cmd_function)does_uri_exist, 0, 0, fixup_exist,
REQUEST_ROUTE|LOCAL_ROUTE},
{0, 0, 0, 0, 0, 0}
Expand Down Expand Up @@ -193,3 +197,9 @@ static int fixup_exist(void** param, int param_no)
}
return 0;
}


static int w_check_uri1(struct sip_msg* msg, char* uri, char* _s)
{
return check_uri(msg, uri, NULL, NULL);
}

0 comments on commit fbe1ed2

Please sign in to comment.