Browse Source

- support for digest credentials selects, supported is:

  @proxy_authorization["realm"] -- Returns entire digest credentials as string
  @proxy_authorization["realm"].username
  @proxy_authorization["realm"].username.user
  @proxy_authorization["realm"].username.domain
  @proxy_authorization["realm"].realm
  @proxy_authorization["realm"].nonce
  @proxy_authorization["realm"].uri
  @proxy_authorization["realm"].cnonce
  @proxy_authorization["realm"].nc
  @proxy_authorization["realm"].response
  @proxy_authorization["realm"].opaque
  @proxy_authorization["realm"].algorithm
  @proxy_authorization["realm"].qop
Jan Janak 19 years ago
parent
commit
3917797b7d
2 changed files with 135 additions and 1 deletions
  1. 97 1
      select_core.c
  2. 38 0
      select_core.h

+ 97 - 1
select_core.c

@@ -37,6 +37,7 @@
 #include "select_buf.h"
 #include "dprint.h"
 #include "trim.h"
+#include "ut.h"
 #include "parser/parser_f.h"
 #include "parser/hf.h"
 #include "parser/parse_from.h"
@@ -47,6 +48,7 @@
 #include "parser/parse_uri.h"
 #include "parser/parse_event.h"
 #include "parser/parse_rr.h"
+#include "parser/digest/digest.h"
 #include "mem/mem.h"
 #include "parser/parse_hname2.h"
 
@@ -794,6 +796,101 @@ int select_cseq_method(str* res, select_t* s, struct sip_msg* msg)
 	return 0;
 }
 
+static struct hdr_field* get_credentials(struct sip_msg* msg, select_t* s)
+{
+	int ret;
+	struct hdr_field* hdr;
+	str realm;
+	hdr_types_t hdr_type;
+
+	     /* Try to find credentials with corresponding realm
+	      * in the message, parse them and return pointer to
+	      * parsed structure
+	      */
+	realm = s->params[1].v.s;
+
+	switch (s->params[0].v.i) {
+	case SEL_AUTH_WWW:
+		hdr_type = HDR_AUTHORIZATION_T;
+		break;
+
+	case SEL_AUTH_PROXY:
+		hdr_type = HDR_PROXYAUTH_T;
+		break;
+
+	default:
+		BUG("Unexpected parameter value \"%d\"\n", s->params[0].v.i);
+		return 0;
+	}
+
+	ret = find_credentials(msg, &realm, hdr_type, &hdr);
+	if (ret < 0) {
+		ERR("Error while looking for credentials\n");
+		return 0;
+	} else if (ret > 0) {
+		return 0;
+	}
+
+	return hdr;
+}
+
+
+int select_auth(str* res, select_t* s, struct sip_msg* msg)
+{
+	struct hdr_field* hdr;
+
+	if (s->n != 2 && s->params[1].type != SEL_PARAM_STR) return -1;
+
+	if (s->params[0].type != SEL_PARAM_DIV) {
+		BUG("Last parameter should have type DIV (converted)\n");
+		return -1;
+	}
+
+        hdr = get_credentials(msg, s);
+	if (!hdr) return -1;
+	RETURN0_res(hdr->body);
+}
+
+int select_auth_param(str* res, select_t* s, struct sip_msg* msg)
+{
+	struct hdr_field* hdr;
+	dig_cred_t* cred;
+
+	if (s->n != 3 && s->n != 4 || s->params[s->n - 1].type != SEL_PARAM_DIV) return -1;
+
+	hdr = get_credentials(msg, s);
+	if (!hdr) return 1;
+	cred = &((auth_body_t*)hdr->parsed)->digest;
+
+	switch(s->params[s->n - 1].v.i) {
+	case SEL_AUTH_USER:     RETURN0_res(cred->username.user);
+	case SEL_AUTH_DOMAIN:   RETURN0_res(cred->username.domain);
+	case SEL_AUTH_USERNAME: RETURN0_res(cred->username.whole);
+	case SEL_AUTH_REALM:    RETURN0_res(cred->realm);
+	case SEL_AUTH_NONCE:    RETURN0_res(cred->nonce);
+	case SEL_AUTH_URI:      RETURN0_res(cred->uri);
+	case SEL_AUTH_CNONCE:   RETURN0_res(cred->cnonce);
+	case SEL_AUTH_NC:       RETURN0_res(cred->nc);
+	case SEL_AUTH_RESPONSE: RETURN0_res(cred->response);
+	case SEL_AUTH_OPAQUE:   RETURN0_res(cred->opaque);
+	case SEL_AUTH_ALG:      RETURN0_res(cred->alg.alg_str);
+	case SEL_AUTH_QOP:      RETURN0_res(cred->qop.qop_str);
+	default:
+		BUG("Unsupported digest credentials parameter in select\n");
+		return -1;
+	}
+}
+
+int select_auth_username(str* res, select_t* s, struct sip_msg* msg)
+{
+	return select_auth_param(res, s, msg);
+}
+
+int select_auth_username_comp(str* res, select_t* s, struct sip_msg* msg)
+{
+	return select_auth_param(res, s, msg);
+}
+
 ABSTRACT_F(select_any_nameaddr)
 
 int select_nameaddr_name(str* res, select_t* s, struct sip_msg* msg)
@@ -834,4 +931,3 @@ int select_nameaddr_uri(str* res, select_t* s, struct sip_msg* msg)
 	res->len=p-res->s;
 	return 0;
 }
-

+ 38 - 0
select_core.h

@@ -44,6 +44,23 @@ enum {
 	SEL_PARAM_BRANCH, SEL_PARAM_RPORT, SEL_PARAM_I, SEL_PARAM_ALIAS
        };
 
+enum {
+	SEL_AUTH_PROXY,
+	SEL_AUTH_WWW,
+	SEL_AUTH_USERNAME,
+	SEL_AUTH_USER,
+	SEL_AUTH_DOMAIN,
+	SEL_AUTH_REALM,
+	SEL_AUTH_NONCE,
+	SEL_AUTH_URI,
+	SEL_AUTH_CNONCE,
+	SEL_AUTH_NC,
+	SEL_AUTH_RESPONSE,
+	SEL_AUTH_OPAQUE,
+	SEL_AUTH_ALG,
+	SEL_AUTH_QOP
+};
+
 SELECT_F(select_ruri)
 SELECT_F(select_from)
 SELECT_F(select_from_uri)
@@ -97,6 +114,11 @@ SELECT_F(select_cseq)
 SELECT_F(select_cseq_method)
 SELECT_F(select_cseq_num)
 
+SELECT_F(select_auth)
+SELECT_F(select_auth_param)
+SELECT_F(select_auth_username)
+SELECT_F(select_auth_username_comp)
+
 static select_row_t select_core[] = {
 	{ NULL, SEL_PARAM_STR, STR_STATIC_INIT("ruri"), select_ruri, 0},
 	{ select_ruri, SEL_PARAM_STR, STR_NULL, select_any_uri, NESTED},
@@ -166,6 +188,22 @@ static select_row_t select_core[] = {
 
 	{ NULL, SEL_PARAM_STR, STR_STATIC_INIT("msg"), select_msgheader, SEL_PARAM_EXPECTED},
 	{ select_msgheader, SEL_PARAM_STR, STR_NULL, select_anyheader, OPTIONAL | CONSUME_NEXT_INT | FIXUP_CALL},
+
+	{ NULL, SEL_PARAM_STR, STR_STATIC_INIT("proxy_authorization"), select_auth, CONSUME_NEXT_STR | DIVERSION | SEL_AUTH_PROXY},
+	{ NULL, SEL_PARAM_STR, STR_STATIC_INIT("authorization"), select_auth, CONSUME_NEXT_STR | DIVERSION | SEL_AUTH_WWW}, 
+	{ select_auth, SEL_PARAM_STR, STR_STATIC_INIT("username"), select_auth_username, DIVERSION | SEL_AUTH_USERNAME},
+	{ select_auth, SEL_PARAM_STR, STR_STATIC_INIT("realm"), select_auth_param, DIVERSION | SEL_AUTH_REALM},
+	{ select_auth, SEL_PARAM_STR, STR_STATIC_INIT("nonce"), select_auth_param, DIVERSION | SEL_AUTH_NONCE},
+	{ select_auth, SEL_PARAM_STR, STR_STATIC_INIT("uri"), select_auth_param, DIVERSION | SEL_AUTH_URI},
+	{ select_auth, SEL_PARAM_STR, STR_STATIC_INIT("cnonce"), select_auth_param, DIVERSION | SEL_AUTH_CNONCE},
+	{ select_auth, SEL_PARAM_STR, STR_STATIC_INIT("nc"), select_auth_param, DIVERSION | SEL_AUTH_NC},
+	{ select_auth, SEL_PARAM_STR, STR_STATIC_INIT("response"), select_auth_param, DIVERSION | SEL_AUTH_RESPONSE},
+	{ select_auth, SEL_PARAM_STR, STR_STATIC_INIT("opaque"), select_auth_param, DIVERSION | SEL_AUTH_OPAQUE},
+	{ select_auth, SEL_PARAM_STR, STR_STATIC_INIT("algorithm"), select_auth_param, DIVERSION | SEL_AUTH_ALG},
+	{ select_auth, SEL_PARAM_STR, STR_STATIC_INIT("qop"), select_auth_param, DIVERSION | SEL_AUTH_QOP},
+	{ select_auth_username, SEL_PARAM_STR, STR_STATIC_INIT("user"), select_auth_username_comp, DIVERSION | SEL_AUTH_USER},
+	{ select_auth_username, SEL_PARAM_STR, STR_STATIC_INIT("domain"), select_auth_username_comp, DIVERSION | SEL_AUTH_DOMAIN},
+
 	{ select_anyheader, SEL_PARAM_STR, STR_STATIC_INIT("nameaddr"), select_any_nameaddr, NESTED | CONSUME_NEXT_STR},
 	{ NULL, SEL_PARAM_INT, STR_NULL, NULL, 0}
 };