Răsfoiți Sursa

uri_db: rework the possibiltiy to use any sip uri (#1034)

* 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
Rick 8 ani în urmă
părinte
comite
fbe1ed25ee
3 a modificat fișierele cu 104 adăugiri și 60 ștergeri
  1. 84 51
      src/modules/uri_db/checks.c
  2. 5 4
      src/modules/uri_db/checks.h
  3. 15 5
      src/modules/uri_db/uri_db.c

+ 84 - 51
src/modules/uri_db/checks.c

@@ -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
  *
  */
@@ -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];
@@ -55,19 +57,6 @@ 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) {
@@ -75,6 +64,31 @@ static inline int check_username(struct sip_msg* _m, struct sip_uri *_uri)
 		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
@@ -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)
@@ -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 {
@@ -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;
 			}
@@ -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);
 }
 
 
@@ -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);
 }
 
 
@@ -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);
@@ -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");
@@ -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;
 	}
 

+ 5 - 4
src/modules/uri_db/checks.h

@@ -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
  *
  */
@@ -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);
 
 
 /*

+ 15 - 5
src/modules/uri_db/uri_db.c

@@ -1,4 +1,4 @@
-/* 
+/*
  * Various URI related functions
  *
  * Copyright (C) 2001-2003 FhG Fokus
@@ -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
  *
  */
@@ -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
  */
@@ -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}
@@ -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);
+}