ソースを参照

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 年 前
コミット
30bec8e614
5 ファイル変更223 行追加19 行削除
  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]>
    <[email protected]>
 
 
-   Copyright © 2009-2010 asipto.com
+   Copyright © 2009-2010 asipto.com
 
 
-   Copyright © 2005 Voice Sistem
+   Copyright © 2005 Voice Sistem
      __________________________________________________________________
      __________________________________________________________________
 
 
    Table of Contents
    Table of Contents
@@ -49,6 +49,7 @@ Ramona-Elena Modroiu
               4.4. uac_auth()
               4.4. uac_auth()
               4.5. uac_req_send()
               4.5. uac_req_send()
               4.6. uac_reg_lookup(uuid, dst)
               4.6. uac_reg_lookup(uuid, dst)
+              4.7. uac_reg_request_to(user, mode)
 
 
         5. Exported pseudo-variables
         5. Exported pseudo-variables
         6. Remote Registration
         6. Remote Registration
@@ -70,7 +71,8 @@ Ramona-Elena Modroiu
    1.13. uac_auth usage
    1.13. uac_auth usage
    1.14. uac_req_send usage
    1.14. uac_req_send usage
    1.15. uac_reg_lookup 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
 Chapter 1. Admin Guide
 
 
@@ -102,6 +104,7 @@ Chapter 1. Admin Guide
         4.4. uac_auth()
         4.4. uac_auth()
         4.5. uac_req_send()
         4.5. uac_req_send()
         4.6. uac_reg_lookup(uuid, dst)
         4.6. uac_reg_lookup(uuid, dst)
+        4.7. uac_reg_request_to(user, mode)
 
 
    5. Exported pseudo-variables
    5. Exported pseudo-variables
    6. Remote Registration
    6. Remote Registration
@@ -134,7 +137,7 @@ Chapter 1. Admin Guide
    The following modules must be loaded before this module:
    The following modules must be loaded before this module:
      * TM - Transaction Module
      * TM - Transaction Module
      * RR - Record-Route Module, but only if restore mode for FROM URI is
      * 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
 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
    Name of Record-Route header parameter that will be used to store
    (encoded) the original FROM URI.
    (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
    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)
 3.2. from_restore_mode (string)
 
 
    There are 3 mode of restoring the original FROM URI:
    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.
        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
        sequential requests - this must be manually updated based on
        original URI.
        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.
        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
    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
    The definition of an AVP that might contain the realm to be used to
    perform authentication.
    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
    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
    The definition of an AVP that might contain the username to be used to
    perform authentication.
    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
    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
    The definition of an AVP that might contain the password to be used to
    perform authentication.
    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
    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.4. uac_auth()
    4.5. uac_req_send()
    4.5. uac_req_send()
    4.6. uac_reg_lookup(uuid, dst)
    4.6. uac_reg_lookup(uuid, dst)
+   4.7. uac_reg_request_to(user, mode)
 
 
 4.1.  uac_replace_from(display,uri)
 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
 5. Exported pseudo-variables
 
 
      * $uac_req(key)
      * $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
    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.
    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")) {
     if(uac_reg_lookup("$rU", "$ru")) {
         xlog("request from a remote SIP provider [$ou => $ru]\n");
         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");
     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>
 				</programlisting>
 			</example>
 			</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_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_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_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_from1(void** param, int param_no);
 static int fixup_replace_from2(void** param, int param_no);
 static int fixup_replace_from2(void** param, int param_no);
 static int mod_init(void);
 static int mod_init(void);
@@ -112,6 +113,8 @@ static cmd_export_t cmds[]={
 		ONREPLY_ROUTE | BRANCH_ROUTE | ERROR_ROUTE | LOCAL_ROUTE},
 		ONREPLY_ROUTE | BRANCH_ROUTE | ERROR_ROUTE | LOCAL_ROUTE},
 	{"uac_reg_lookup",  (cmd_function)w_uac_reg_lookup,  2, fixup_pvar_pvar,
 	{"uac_reg_lookup",  (cmd_function)w_uac_reg_lookup,  2, fixup_pvar_pvar,
 		fixup_free_pvar_pvar, ANY_ROUTE },
 		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}
 	{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);
 	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 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;
 	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] = {
 static const char* rpc_uac_reg_dump_doc[2] = {
 	"Dump the contents of user registrations table.",
 	"Dump the contents of user registrations table.",
 	0
 	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_init_rpc(void);
 
 
 int  uac_reg_lookup(struct sip_msg *msg, str *src, pv_spec_t *dst, int mode);
 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
 #endif