[asterisk-commits] mmichelson: branch group/pimp_my_sip r380244 - /team/group/pimp_my_sip/res/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Jan 28 01:42:58 CST 2013


Author: mmichelson
Date: Mon Jan 28 01:42:54 2013
New Revision: 380244

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=380244
Log:
Allow multiple contact headers and fix misuse of ast_free after resolving addresses.

The most common case for contact ACLs is for REGISTER requests. Of the various SIP
request types, REGISTER is most likely to contain multiple contact headers. With
this change, all contact headers are checked against contact ACLs.

Fixed a bug freeing memory. I had thought individual addresses returned by
ast_sockaddr_resolve() were to be freed, but you just need to free the block.


Modified:
    team/group/pimp_my_sip/res/res_sip_acl.c

Modified: team/group/pimp_my_sip/res/res_sip_acl.c
URL: http://svnview.digium.com/svn/asterisk/team/group/pimp_my_sip/res/res_sip_acl.c?view=diff&rev=380244&r1=380243&r2=380244
==============================================================================
--- team/group/pimp_my_sip/res/res_sip_acl.c (original)
+++ team/group/pimp_my_sip/res/res_sip_acl.c Mon Jan 28 01:42:54 2013
@@ -38,11 +38,30 @@
 	struct ast_acl_list *contact_acl;
 };
 
-static int extract_contact_addr(pjsip_rx_data *rdata, struct ast_sockaddr **addrs)
-{
-	pjsip_contact_hdr *contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL);
+static int apply_acl(pjsip_rx_data *rdata, struct ast_acl_list *acl)
+{
+	struct ast_sockaddr addr;
+
+	if (ast_acl_list_is_empty(acl)) {
+		return 0;
+	}
+
+	memset(&addr, 0, sizeof(addr));
+	ast_sockaddr_parse(&addr, rdata->pkt_info.src_name, PARSE_PORT_FORBID);
+	ast_sockaddr_set_port(&addr, rdata->pkt_info.src_port);
+
+	if (ast_apply_acl(acl, &addr, "SIP ACL: ") != AST_SENSE_ALLOW) {
+		ast_log(LOG_WARNING, "Incoming SIP message from %s did not pass ACL test\n", ast_sockaddr_stringify(&addr));
+		return 1;
+	}
+	return 0;
+}
+
+static int extract_contact_addr(pjsip_contact_hdr *contact, struct ast_sockaddr **addrs)
+{
 	pjsip_sip_uri *sip_uri;
 	char host[256];
+
 	if (!contact) {
 		return 0;
 	}
@@ -52,25 +71,6 @@
 	sip_uri = pjsip_uri_get_uri(contact->uri);
 	ast_copy_pj_str(host, &sip_uri->host, sizeof(host));
 	return ast_sockaddr_resolve(addrs, host, PARSE_PORT_FORBID, AST_AF_UNSPEC);
-}
-
-static int apply_acl(pjsip_rx_data *rdata, struct ast_acl_list *acl)
-{
-	struct ast_sockaddr addr;
-
-	if (ast_acl_list_is_empty(acl)) {
-		return 0;
-	}
-
-	memset(&addr, 0, sizeof(addr));
-	ast_sockaddr_parse(&addr, rdata->pkt_info.src_name, PARSE_PORT_FORBID);
-	ast_sockaddr_set_port(&addr, rdata->pkt_info.src_port);
-
-	if (ast_apply_acl(acl, &addr, "SIP ACL: ") != AST_SENSE_ALLOW) {
-		ast_log(LOG_WARNING, "Incoming SIP message from %s did not pass ACL test\n", ast_sockaddr_stringify(&addr));
-		return 1;
-	}
-	return 0;
 }
 
 static int apply_contact_acl(pjsip_rx_data *rdata, struct ast_acl_list *contact_acl)
@@ -79,21 +79,29 @@
 	int forbidden = 0;
 	struct ast_sockaddr *contact_addrs;
 	int i;
+	pjsip_contact_hdr *contact = (pjsip_contact_hdr *)&rdata->msg_info.msg->hdr;
 
 	if (ast_acl_list_is_empty(contact_acl)) {
 		return 0;
 	}
 
-	num_contact_addrs = extract_contact_addr(rdata, &contact_addrs);
-	if (num_contact_addrs <= 0) {
-		return 0;
-	}
-	for (i = 0; i < num_contact_addrs; ++i) {
-		if (ast_apply_acl(contact_acl, &contact_addrs[i], "SIP Contact ACL: ") != AST_SENSE_ALLOW) {
-			ast_log(LOG_WARNING, "Incoming SIP message from %s did not pass ACL test\n", ast_sockaddr_stringify(&contact_addrs[i]));
-			forbidden = 1;
+	while ((contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, contact->next))) {
+		num_contact_addrs = extract_contact_addr(contact, &contact_addrs);
+		if (num_contact_addrs <= 0) {
+			continue;
 		}
-		ast_free(&contact_addrs[i]);
+		for (i = 0; i < num_contact_addrs; ++i) {
+			if (ast_apply_acl(contact_acl, &contact_addrs[i], "SIP Contact ACL: ") != AST_SENSE_ALLOW) {
+				ast_log(LOG_WARNING, "Incoming SIP message from %s did not pass ACL test\n", ast_sockaddr_stringify(&contact_addrs[i]));
+				forbidden = 1;
+				break;
+			}
+		}
+		ast_free(contact_addrs);
+		if (forbidden) {
+			/* No use checking other contacts if we already have failed ACL check */
+			break;
+		}
 	}
 
 	return forbidden;




More information about the asterisk-commits mailing list