Browse Source

modules_k/uac: Add reg_request_to function

This function will lookup a local user from the registration table and
prepares mesasage variables so the request can be sent to the remote
user, providing authentiction via uac_auth().
Alex Hermann 14 năm trước cách đây
mục cha
commit
30bec8e614
5 tập tin đã thay đổi với 223 bổ sung19 xóa
  1. 56 19
      modules_k/uac/README
  2. 41 0
      modules_k/uac/doc/uac_admin.xml
  3. 34 0
      modules_k/uac/uac.c
  4. 91 0
      modules_k/uac/uac_reg.c
  5. 1 0
      modules_k/uac/uac_reg.h

+ 56 - 19
modules_k/uac/README

@@ -14,9 +14,9 @@ Ramona-Elena Modroiu
 
    <[email protected]>
 
-   Copyright © 2009-2010 asipto.com
+   Copyright © 2009-2010 asipto.com
 
-   Copyright © 2005 Voice Sistem
+   Copyright © 2005 Voice Sistem
      __________________________________________________________________
 
    Table of Contents
@@ -49,6 +49,7 @@ Ramona-Elena Modroiu
               4.4. uac_auth()
               4.5. uac_req_send()
               4.6. uac_reg_lookup(uuid, dst)
+              4.7. uac_reg_request_to(user, mode)
 
         5. Exported pseudo-variables
         6. Remote Registration
@@ -70,7 +71,8 @@ Ramona-Elena Modroiu
    1.13. uac_auth usage
    1.14. uac_req_send usage
    1.15. uac_reg_lookup usage
-   1.16. lookup remote registrations usage
+   1.16. uac_reg_request_to usage
+   1.17. lookup remote registrations usage
 
 Chapter 1. Admin Guide
 
@@ -102,6 +104,7 @@ Chapter 1. Admin Guide
         4.4. uac_auth()
         4.5. uac_req_send()
         4.6. uac_reg_lookup(uuid, dst)
+        4.7. uac_reg_request_to(user, mode)
 
    5. Exported pseudo-variables
    6. Remote Registration
@@ -134,7 +137,7 @@ Chapter 1. Admin Guide
    The following modules must be loaded before this module:
      * TM - Transaction Module
      * RR - Record-Route Module, but only if restore mode for FROM URI is
-       set to “auto�.
+       set to "auto".
 
 2.2. External Libraries or Applications
 
@@ -159,7 +162,7 @@ Chapter 1. Admin Guide
    Name of Record-Route header parameter that will be used to store
    (encoded) the original FROM URI.
 
-   This parameter is optional, it's default value being “vsf�.
+   This parameter is optional, it's default value being "vsf".
 
    Example 1.1. Set rr_store_param parameter
 ...
@@ -169,15 +172,15 @@ modparam("uac","rr_store_param","my_param")
 3.2. from_restore_mode (string)
 
    There are 3 mode of restoring the original FROM URI:
-     * “none� - no information about original URI is stored; restoration
+     * "none" - no information about original URI is stored; restoration
        is not possible.
-     * “manual� - all following replies will be restored, but not also the
+     * "manual" - all following replies will be restored, but not also the
        sequential requests - this must be manually updated based on
        original URI.
-     * “auto� - all sequential requests and replies will be automatically
+     * "auto" - all sequential requests and replies will be automatically
        updated based on stored original URI.
 
-   This parameter is optional, it's default value being “auto�.
+   This parameter is optional, it's default value being "auto".
 
    Example 1.2. Set from_restore_mode parameter
 ...
@@ -213,9 +216,9 @@ modparam("uac","credential","username:domain:password")
    The definition of an AVP that might contain the realm to be used to
    perform authentication.
 
-   If you define it, you also need to define “auth_username_avp�
-   (Section 3.6, “auth_username_avp (string)�) and “auth_username_avp�
-   (Section 3.7, “auth_password_avp (string)�).
+   If you define it, you also need to define "auth_username_avp"
+   (Section 3.6, "auth_username_avp (string)") and "auth_username_avp"
+   (Section 3.7, "auth_password_avp (string)").
 
    Example 1.5. Set auth_realm_avp parameter
 ...
@@ -227,9 +230,9 @@ modparam("uac","auth_realm_avp","$avp(i:10)")
    The definition of an AVP that might contain the username to be used to
    perform authentication.
 
-   If you define it, you also need to define “auth_realm_avp�
-   (Section 3.5, “auth_realm_avp (string)�) and “auth_username_avp�
-   (Section 3.7, “auth_password_avp (string)�).
+   If you define it, you also need to define "auth_realm_avp"
+   (Section 3.5, "auth_realm_avp (string)") and "auth_username_avp"
+   (Section 3.7, "auth_password_avp (string)").
 
    Example 1.6. Set auth_username_avp parameter
 ...
@@ -241,9 +244,9 @@ modparam("uac","auth_username_avp","$avp(i:11)")
    The definition of an AVP that might contain the password to be used to
    perform authentication.
 
-   If you define it, you also need to define “auth_password_avp�
-   (Section 3.7, “auth_password_avp (string)�) and “auth_username_avp�
-   (Section 3.7, “auth_password_avp (string)�).
+   If you define it, you also need to define "auth_password_avp"
+   (Section 3.7, "auth_password_avp (string)") and "auth_username_avp"
+   (Section 3.7, "auth_password_avp (string)").
 
    Example 1.7. Set auth_password_avp parameter
 ...
@@ -278,6 +281,7 @@ modparam("uac", "reg_contact_addr", "192.168.1.2:5080")
    4.4. uac_auth()
    4.5. uac_req_send()
    4.6. uac_reg_lookup(uuid, dst)
+   4.7. uac_reg_request_to(user, mode)
 
 4.1.  uac_replace_from(display,uri)
 
@@ -371,6 +375,39 @@ if(uac_reg_lookup("$rU", "$ru"))
 }
 ...
 
+4.7.  uac_reg_request_to(user, mode)
+
+   This function can be used to send an authenticated request to a remote
+   user in the uac registrations table. It sets the request-uri, dst-uri
+   and auth_*_avp pv's to the values that correspond to the supplied user.
+
+   The mode indicates whether the user should match the local uuid
+   (mode=0), or the username (mode=1).
+
+   The auth_*_avp module parameters must be set to valid pv's.
+
+   This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
+   BRANCH_ROUTE.
+
+   Example 1.16. uac_reg_request_to usage
+...
+
+if(uac_reg_request_to("$fU", 0))
+{
+        xlog("L_NOTICE", "Found remote user [$rU] on [$rd] via [$du]");
+        t_on_failure("REMOTE_AUTH");
+
+        t_relay()
+}
+...
+failure_route[REMOTE_AUTH] {
+        if ($T_reply_code == 401 or $T_reply_code == 407) {
+                xlog("L_NOTICE", "Remote asked for authentication");
+                uac_auth()
+        }
+}
+...
+
 5. Exported pseudo-variables
 
      * $uac_req(key)
@@ -411,7 +448,7 @@ if(uac_reg_lookup("$rU", "$ru"))
    if the call is coming from a remote SIP provider and can change the
    R-URI to local username@domain. Afterwards you can run location lookup.
 
-   Example 1.16. lookup remote registrations usage
+   Example 1.17. lookup remote registrations usage
 ...
     if(uac_reg_lookup("$rU", "$ru")) {
         xlog("request from a remote SIP provider [$ou => $ru]\n");

+ 41 - 0
modules_k/uac/doc/uac_admin.xml

@@ -433,6 +433,47 @@ if(uac_reg_lookup("$rU", "$ru"))
 {
     lookup("location");
 }
+...
+				</programlisting>
+			</example>
+		</section>
+		<section>
+			<title>
+				<function moreinfo="none">uac_reg_request_to(user, mode)</function>
+			</title>
+			<para>
+			This function can be used to send an authenticated request to a remote user in 
+			the uac registrations table. It sets the request-uri, dst-uri and auth_*_avp
+			pv's to the values that correspond to the supplied user.
+			</para>
+			<para>
+			The mode indicates whether the user should match the local uuid (mode=0), or the username (mode=1).
+			</para>
+			<para>
+			The auth_*_avp module parameters must be set to valid pv&apos;s.
+			</para>
+			<para>
+			This function can be used from REQUEST_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE.
+			</para>
+			<example>
+				<title><function>uac_reg_request_to</function> usage</title>
+				<programlisting format="linespecific">
+...
+
+if(uac_reg_request_to("$fU", 0))
+{
+	xlog("L_NOTICE", "Found remote user [$rU] on [$rd] via [$du]");
+	t_on_failure("REMOTE_AUTH");
+
+	t_relay()
+}
+...
+failure_route[REMOTE_AUTH] {
+	if ($T_reply_code == 401 or $T_reply_code == 407) {
+		xlog("L_NOTICE", "Remote asked for authentication");
+		uac_auth()
+	}
+}
 ...
 				</programlisting>
 			</example>

+ 34 - 0
modules_k/uac/uac.c

@@ -83,6 +83,7 @@ static int w_replace_from2(struct sip_msg* msg, char* str, char* str2);
 static int w_restore_from(struct sip_msg* msg,  char* foo, char* bar);
 static int w_uac_auth(struct sip_msg* msg, char* str, char* str2);
 static int w_uac_reg_lookup(struct sip_msg* msg,  char* src, char* dst);
+static int w_uac_reg_request_to(struct sip_msg* msg,  char* src, char* mode_s);
 static int fixup_replace_from1(void** param, int param_no);
 static int fixup_replace_from2(void** param, int param_no);
 static int mod_init(void);
@@ -112,6 +113,8 @@ static cmd_export_t cmds[]={
 		ONREPLY_ROUTE | BRANCH_ROUTE | ERROR_ROUTE | LOCAL_ROUTE},
 	{"uac_reg_lookup",  (cmd_function)w_uac_reg_lookup,  2, fixup_pvar_pvar,
 		fixup_free_pvar_pvar, ANY_ROUTE },
+	{"uac_reg_request_to",  (cmd_function)w_uac_reg_request_to,  2, fixup_pvar_uint, fixup_free_pvar_uint,
+		REQUEST_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE },
 
 	{0,0,0,0,0,0}
 };
@@ -462,3 +465,34 @@ static int w_uac_reg_lookup(struct sip_msg* msg,  char* src, char* dst)
 	return uac_reg_lookup(msg, &val.rs, dpv, 0);
 }
 
+
+static int w_uac_reg_request_to(struct sip_msg* msg, char* src, char* mode_s)
+{
+	pv_spec_t *spv;
+	pv_value_t val;
+	unsigned int mode;
+
+	mode = (unsigned int)(long)mode_s;
+
+	spv = (pv_spec_t*)src;
+	if(pv_get_spec_value(msg, spv, &val) != 0)
+	{
+		LM_ERR("cannot get src uri value\n");
+		return -1;
+	}
+
+	if (!(val.flags & PV_VAL_STR))
+	{
+	    LM_ERR("src pv value is not string\n");
+	    return -1;
+	}
+
+	if (mode > 1)
+	{
+		LM_ERR("invalid mode\n");
+		return -1;
+	}
+
+	return uac_reg_request_to(msg, &val.rs, mode);
+}
+

+ 91 - 0
modules_k/uac/uac_reg.c

@@ -130,6 +130,9 @@ CREATE TABLE uacreg (
 
 
 extern struct tm_binds uac_tmb;
+extern pv_spec_t auth_username_spec;
+extern pv_spec_t auth_realm_spec;
+extern pv_spec_t auth_password_spec;
 
 /**
  *
@@ -925,6 +928,94 @@ int  uac_reg_lookup(struct sip_msg *msg, str *src, pv_spec_t *dst, int mode)
 	return 1;
 }
 
+/**
+ *
+ */
+int uac_reg_request_to(struct sip_msg *msg, str *src, unsigned int mode)
+{
+	char ruri[MAX_URI_SIZE];
+	struct sip_uri puri;
+	reg_uac_t *reg = NULL;
+	pv_value_t val;
+	struct action act;
+	struct run_act_ctx ra_ctx;
+
+	switch(mode)
+	{
+		case 0:
+			reg = reg_ht_get_byuuid(src);
+			break;
+		case 1:
+			if(reg_use_domain)
+			{
+				if (parse_uri(src->s, src->len, &puri)!=0)
+				{
+					LM_ERR("failed to parse uri\n");
+					return -2;
+				}
+				reg = reg_ht_get_byuser(&puri.user, &puri.host);
+			} else {
+				reg = reg_ht_get_byuser(src, NULL);
+			}
+			break;
+		default:
+			LM_ERR("unknown mode: %d\n", mode);
+			return -1;
+	}
+
+	if(reg==NULL)
+	{
+		LM_DBG("no user: %.*s\n", src->len, src->s);
+		return -1;
+	}
+
+	// Set uri ($ru)
+	snprintf(ruri, MAX_URI_SIZE, "sip:%.*s@%.*s",
+		reg->r_username.len, reg->r_username.s,
+		reg->r_domain.len, reg->r_domain.s);
+	memset(&act, 0, sizeof(act));
+	act.type = SET_URI_T;
+	act.val[0].type = STRING_ST;
+	act.val[0].u.string = ruri;
+	init_run_actions_ctx(&ra_ctx);
+	if (do_action(&ra_ctx, &act, msg) < 0) {
+		LM_ERR("error while setting request uri\n");
+		return -1;
+	}
+
+	// Set auth_proxy ($du)
+	if (set_dst_uri(msg, &reg->auth_proxy) < 0) {
+		LM_ERR("error while setting outbound proxy\n");
+		return -1;
+	}
+
+	memset(&val, 0, sizeof(pv_value_t));
+	val.flags |= PV_VAL_STR;
+
+	// Set auth_realm
+	val.rs = reg->realm;
+	if(pv_set_spec_value(msg, &auth_realm_spec, 0, &val)!=0) {
+		LM_ERR("error while setting auth_realm\n");
+		return -1;
+	}
+
+	// Set auth_username
+	val.rs = reg->auth_username;
+	if(pv_set_spec_value(msg, &auth_username_spec, 0, &val)!=0) {
+		LM_ERR("error while setting auth_username\n");
+		return -1;
+	}
+
+	// Set auth_password
+	val.rs = reg->auth_password;
+	if(pv_set_spec_value(msg, &auth_password_spec, 0, &val)!=0) {
+		LM_ERR("error while setting auth_password\n");
+		return -1;
+	}
+
+	return 1;
+}
+
 static const char* rpc_uac_reg_dump_doc[2] = {
 	"Dump the contents of user registrations table.",
 	0

+ 1 - 0
modules_k/uac/uac_reg.h

@@ -52,4 +52,5 @@ void uac_reg_timer(unsigned int ticks);
 int uac_reg_init_rpc(void);
 
 int  uac_reg_lookup(struct sip_msg *msg, str *src, pv_spec_t *dst, int mode);
+int  uac_reg_request_to(struct sip_msg *msg, str *src, unsigned int mode);
 #endif