[svn-commits] russell: branch group/security_events r209716 - in /team/group/security_event...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Jul 31 17:03:02 CDT 2009


Author: russell
Date: Fri Jul 31 17:02:51 2009
New Revision: 209716

URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=209716
Log:
resolve, reset

Modified:
    team/group/security_events/   (props changed)
    team/group/security_events/channels/chan_sip.c
    team/group/security_events/configs/sip.conf.sample
    team/group/security_events/main/event.c

Propchange: team/group/security_events/
------------------------------------------------------------------------------
    automerge = *

Propchange: team/group/security_events/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Fri Jul 31 17:02:51 2009
@@ -1,1 +1,1 @@
-/trunk:1-209639
+/trunk:1-209715

Modified: team/group/security_events/channels/chan_sip.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/security_events/channels/chan_sip.c?view=diff&rev=209716&r1=209715&r2=209716
==============================================================================
--- team/group/security_events/channels/chan_sip.c (original)
+++ team/group/security_events/channels/chan_sip.c Fri Jul 31 17:02:51 2009
@@ -1188,6 +1188,7 @@
 	int callevents;			/*!< Whether we send manager events or not */
 	int regextenonqualify;  	/*!< Whether to add/remove regexten when qualifying peers */
 	int matchexterniplocally;	/*!< Match externip/externhost setting against localnet setting */
+	unsigned int disallowed_methods; /*!< methods that we should never try to use */
 	int notifyringing;		/*!< Send notifications on ringing */
 	int notifyhold;			/*!< Send notifications on hold */
 	enum notifycid_setting notifycid; /*!< Send CID with ringing notifications */
@@ -1819,11 +1820,15 @@
 
 	struct sip_subscription_mwi *mwi;       /*!< If this is a subscription MWI dialog, to which subscription */
 	struct timeval session_tv;		/*!< The time this dialog started */
-	/*! The SIP methods allowed on this dialog. We get this information from the Allow header present in 
-	 * the peer's REGISTER. If peer does not register with us, then we will use the first transaction we
-	 * have with this peer to determine its allowed methods.
+	/*! The SIP methods supported by this peer. We get this information from the Allow header of the first
+	 * message we receive from an endpoint during a dialog.
 	 */
 	unsigned int allowed_methods;
+	/*! Some peers are not trustworthy with their Allow headers, and so we need to override their wicked
+	 * ways through configuration. This is a copy of the peer's disallowed_methods, so that we can apply them
+	 * to the sip_pvt at various stages of dialog establishment
+	 */
+	unsigned int disallowed_methods;
 	/*! When receiving an SDP offer, it is important to take note of what media types were offered.
 	 * By doing this, even if we don't want to answer a particular media stream with something meaningful, we can
 	 * still put an m= line in our answer with the port set to 0.
@@ -2029,7 +2034,7 @@
 	
 	/*XXX Seems like we suddenly have two flags with the same content. Why? To be continued... */
 	enum sip_peer_type type; /*!< Distinguish between "user" and "peer" types. This is used solely for CLI and manager commands */
-	unsigned int allowed_methods;
+	unsigned int disallowed_methods;
 };
 
 
@@ -5118,7 +5123,7 @@
 	dialog->rtptimeout = peer->rtptimeout;
 	dialog->peerauth = peer->auth;
 	dialog->maxcallbitrate = peer->maxcallbitrate;
-	dialog->allowed_methods = peer->allowed_methods;
+	dialog->disallowed_methods = peer->disallowed_methods;
 	if (ast_strlen_zero(dialog->tohost))
 		ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr));
 	if (!ast_strlen_zero(peer->fromdomain)) {
@@ -5212,6 +5217,7 @@
 	}
 
 	ast_string_field_set(dialog, tohost, peername);
+	dialog->allowed_methods &= ~sip_cfg.disallowed_methods;
 
 	/* Get the outbound proxy information */
 	ref_proxy(dialog, obproxy_get(dialog, NULL));
@@ -7107,6 +7113,7 @@
 	p->branch = ast_random();	
 	make_our_tag(p->tag, sizeof(p->tag));
 	p->ocseq = INITIAL_CSEQ;
+	p->allowed_methods = UINT_MAX;
 
 	if (sip_methods[intended_method].need_rtp) {
 		if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && (p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr))) {
@@ -7534,6 +7541,17 @@
 	return ((*allowed_methods) >> method) & 1;
 }
 
+static void mark_parsed_methods(unsigned int *methods, char *methods_str)
+{
+	char *method;
+	for (method = strsep(&methods_str, ","); !ast_strlen_zero(method); method = strsep(&methods_str, ",")) {
+		int id = find_sip_method(ast_skip_blanks(method));
+		if (id == SIP_UNKNOWN) {
+			continue;
+		}
+		mark_method_allowed(methods, id);
+	}
+}
 /*!
  * \brief parse the Allow header to see what methods the endpoint we
  * are communicating with allows.
@@ -7553,7 +7571,6 @@
 static unsigned int parse_allowed_methods(struct sip_request *req)
 {
 	char *allow = ast_strdupa(get_header(req, "Allow"));
-	char *method;
 	unsigned int allowed_methods = SIP_UNKNOWN;
 
 	if (ast_strlen_zero(allow)) {
@@ -7580,13 +7597,7 @@
 		}
 		allow = ast_strip_quoted(methods + 9, "\"", "\"");
 	}
-	for (method = strsep(&allow, ","); !ast_strlen_zero(method); method = strsep(&allow, ",")) {
-		int id = find_sip_method(ast_skip_blanks(method));
-		if (id == SIP_UNKNOWN) {
-			continue;
-		}
-		mark_method_allowed(&allowed_methods, id);
-	}
+	mark_parsed_methods(&allowed_methods, allow);
 	return allowed_methods;
 }
 
@@ -7606,6 +7617,7 @@
 	if (ast_test_flag(&pvt->flags[1], SIP_PAGE2_RPID_UPDATE)) {
 		mark_method_allowed(&pvt->allowed_methods, SIP_UPDATE);
 	}
+	pvt->allowed_methods &= ~(pvt->disallowed_methods);
 
 	return pvt->allowed_methods;
 }
@@ -11889,7 +11901,6 @@
 	manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
 	register_peer_exten(peer, FALSE);	/* Remove regexten */
 	ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
-	peer->allowed_methods = SIP_UNKNOWN;
 
 	/* Do we need to release this peer from memory? 
 		Only for realtime peers and autocreated peers
@@ -11932,13 +11943,11 @@
 	int expire;
 	int port;
 	char *scan, *addr, *port_str, *expiry_str, *username, *contact;
-	char allowed_methods_str[256] = "";
 
 	if (peer->rt_fromcontact) 
 		return;
 	if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data)))
 		return;
-	ast_db_get("SIP/PeerMethods", peer->name, allowed_methods_str, sizeof(allowed_methods_str));
 
 	scan = data;
 	addr = strsep(&scan, ":");
@@ -11964,10 +11973,6 @@
 		ast_string_field_set(peer, username, username);
 	if (contact)
 		ast_string_field_set(peer, fullcontact, contact);
-
-	if (!ast_strlen_zero(allowed_methods_str)) {
-		peer->allowed_methods = atoi(allowed_methods_str);
-	}
 
 	ast_debug(2, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n",
 	    peer->name, peer->username, ast_inet_ntoa(in), port, expire);
@@ -13110,16 +13115,6 @@
 		}
 	}
 	if (peer) {
-		ao2_lock(peer);
-		if (peer->allowed_methods == SIP_UNKNOWN) {
-			peer->allowed_methods = set_pvt_allowed_methods(p, req);
-		}
-		if (!peer->rt_fromcontact) {
-			char allowed_methods_str[256];
-			snprintf(allowed_methods_str, sizeof(allowed_methods_str), "%u", peer->allowed_methods);
-			ast_db_put("SIP/PeerMethods", peer->name, allowed_methods_str);
-		}
-		ao2_unlock(peer);
 		unref_peer(peer, "register_verify: unref_peer: tossing stack peer pointer at end of func");
 	}
 
@@ -14095,11 +14090,8 @@
 	ast_string_field_set(p, mohsuggest, peer->mohsuggest);
 	ast_string_field_set(p, parkinglot, peer->parkinglot);
 	ast_string_field_set(p, engine, peer->engine);
-	if (peer->allowed_methods == SIP_UNKNOWN) {
-		set_pvt_allowed_methods(p, req);
-	} else {
-		p->allowed_methods = peer->allowed_methods;
-	}
+	p->disallowed_methods = peer->disallowed_methods;
+	set_pvt_allowed_methods(p, req);
 	if (peer->callingpres)	/* Peer calling pres setting will override RPID */
 		p->callingpres = peer->callingpres;
 	if (peer->maxms && peer->lastms)
@@ -17784,21 +17776,6 @@
 	else
 		ast_debug(4, "SIP response %d to standard invite\n", resp);
 
-	/* If this is a response to our initial INVITE, we need to set what we can use
-	 * for this peer.
-	 */
-	if (!reinvite && p->allowed_methods == SIP_UNKNOWN) {
-		struct sip_peer *peer = find_peer(p->peername, NULL, 1, FINDPEERS, FALSE);
-		if (!peer || peer->allowed_methods == SIP_UNKNOWN) {
-			set_pvt_allowed_methods(p, req);
-		} else {
-			p->allowed_methods = peer->allowed_methods;
-		}
-		if (peer) {
-			unref_peer(peer, "handle_response_invite: Getting supported methods from peer");
-		}
-	}
-
 	if (p->alreadygone) { /* This call is already gone */
 		ast_debug(1, "Got response on call that is already terminated: %s (ignoring)\n", p->callid);
 		return;
@@ -17825,6 +17802,13 @@
 	/* Final response, clear out pending invite */
 	if ((resp == 200 || resp >= 300) && p->pendinginvite && seqno == p->pendinginvite)
 		p->pendinginvite = 0;
+
+	/* If this is a response to our initial INVITE, we need to set what we can use
+	 * for this peer.
+	 */
+	if (!reinvite) {
+		set_pvt_allowed_methods(p, req);
+	}		
 
 	switch (resp) {
 	case 100:	/* Trying */
@@ -18194,7 +18178,6 @@
 /* \brief Handle SIP response in SUBSCRIBE transaction */
 static void handle_response_subscribe(struct sip_pvt *p, int resp, const char *rest, struct sip_request *req, int seqno)
 {
-	struct sip_peer *peer;
 	if (!p->mwi) {
 		return;
 	}
@@ -18202,15 +18185,7 @@
 	switch (resp) {
 	case 200: /* Subscription accepted */
 		ast_debug(3, "Got 200 OK on subscription for MWI\n");
-		peer = find_peer(p->peername, NULL, 1, FINDPEERS, FALSE);
-		if (!peer || peer->allowed_methods == SIP_UNKNOWN) {
-			set_pvt_allowed_methods(p, req);
-		} else {
-			p->allowed_methods = peer->allowed_methods;
-		}
-		if (peer) {
-			unref_peer(peer, "handle_response_subscribe: Getting supported methods");
-		}
+		set_pvt_allowed_methods(p, req);
 		if (p->options) {
 			ast_free(p->options);
 			p->options = NULL;
@@ -18529,12 +18504,6 @@
 		manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
 			"ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n",
 			peer->name, s, pingtime);
-		if (!is_reachable) {
-			peer->allowed_methods = SIP_UNKNOWN;
-		} else {
-			set_pvt_allowed_methods(p, req);
-			peer->allowed_methods = p->allowed_methods;
-		}
 		if (is_reachable && sip_cfg.regextenonqualify)
 			register_peer_exten(peer, TRUE);
 	}
@@ -18789,7 +18758,7 @@
 		case 501: /* Not Implemented */
 			mark_method_unallowed(&p->allowed_methods, sipmethod);
 			if ((peer = find_peer(p->peername, 0, 1, FINDPEERS, FALSE))) {
-				peer->allowed_methods = p->allowed_methods;
+				mark_method_allowed(&peer->disallowed_methods, sipmethod);
 				unref_peer(peer, "handle_response: marking a specific method as unallowed");
 			}
 			if (sipmethod == SIP_INVITE)
@@ -20316,6 +20285,7 @@
 		/* This is a new invite */
 		/* Handle authentication if this is our first invite */
 		struct ast_party_redirecting redirecting = {{0,},};
+		set_pvt_allowed_methods(p, req);
 		res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin);
 		if (res == AUTH_CHALLENGE_SENT) {
 			p->invitestate = INV_COMPLETED;		/* Needs to restart in another INVITE transaction */
@@ -21601,6 +21571,7 @@
 	if (!req->ignore && !resubscribe) {	/* Set up dialog, new subscription */
 		const char *to = get_header(req, "To");
 		char totag[128];
+		set_pvt_allowed_methods(p, req);
 
 		/* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */
 		if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) {
@@ -23937,6 +23908,7 @@
 	peer->timer_t1 = global_t1;
 	peer->timer_b = global_timer_b;
 	clear_peer_mailboxes(peer);
+	peer->disallowed_methods = sip_cfg.disallowed_methods;
 }
 
 /*! \brief Create temporary peer (used in autocreatepeer mode) */
@@ -24392,6 +24364,9 @@
 			} else {
 				peer->stimer.st_ref = i;
 			}
+		} else if (!strcasecmp(v->name, "disallowed_methods")) {
+			char *disallow = ast_strdupa(v->value);
+			mark_parsed_methods(&peer->disallowed_methods, disallow);
 		}
 	}
 
@@ -24679,6 +24654,7 @@
 	sip_cfg.directrtpsetup = FALSE;		/* Experimental feature, disabled by default */
 	sip_cfg.alwaysauthreject = DEFAULT_ALWAYSAUTHREJECT;
 	sip_cfg.allowsubscribe = FALSE;
+	sip_cfg.disallowed_methods = SIP_UNKNOWN;
 	snprintf(global_useragent, sizeof(global_useragent), "%s %s", DEFAULT_USERAGENT, ast_get_version());
 	snprintf(global_sdpsession, sizeof(global_sdpsession), "%s %s", DEFAULT_SDPSESSION, ast_get_version());
 	snprintf(global_sdpowner, sizeof(global_sdpowner), "%s", DEFAULT_SDPOWNER);
@@ -25171,6 +25147,9 @@
 				ast_log(LOG_WARNING, "Invalid pokepeers '%s' at line %d of %s\n", v->value, v->lineno, config);
 				global_qualify_peers = DEFAULT_QUALIFY_PEERS;
 			}
+		} else if (!strcasecmp(v->name, "disallowed_methods")) {
+			char *disallow = ast_strdupa(v->value);
+			mark_parsed_methods(&sip_cfg.disallowed_methods, disallow);
 		}
 	}
 

Modified: team/group/security_events/configs/sip.conf.sample
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/security_events/configs/sip.conf.sample?view=diff&rev=209716&r1=209715&r2=209716
==============================================================================
--- team/group/security_events/configs/sip.conf.sample (original)
+++ team/group/security_events/configs/sip.conf.sample Fri Jul 31 17:02:51 2009
@@ -100,6 +100,27 @@
                                 ; Set this to your host name or domain name
 udpbindaddr=0.0.0.0             ; IP address to bind UDP listen socket to (0.0.0.0 binds to all)
                                 ; Optionally add a port number, 192.168.1.1:5062 (default is port 5060)
+
+; When a dialog is started with another SIP endpoint, the other endpoint
+; should include an Allow header telling us what SIP methods the endpoint
+; implements. However, some endpoints either do not include an Allow header
+; or lie about what methods they implement. In the former case, Asterisk
+; makes the assumption that the endpoint supports all known SIP methods.
+; If you know that your SIP endpoint does not provide support for a specific
+; method, then you may provide a comma-separated list of methods that your
+; endpoint does not implement in the disallowed_methods option. Note that 
+; if your endpoint is truthful with its Allow header, then there is no need 
+; to set this option. This option may be set in the general section or may
+; be set per endpoint. If this option is set both in the general section and
+; in a peer section, then the peer setting completely overrides the general
+; setting (i.e. the result is *not* the union of the two options).
+;
+; Note also that while Asterisk currently will parse an Allow header to learn
+; what methods an endpoint supports, the only actual use for this currently
+; is for determining if Asterisk may send connected line UPDATE requests. Its
+; use may be expanded in the future.
+;
+; disallowed_methods = UPDATE
 
 ;
 ; Note that the TCP and TLS support for chan_sip is currently considered

Modified: team/group/security_events/main/event.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/group/security_events/main/event.c?view=diff&rev=209716&r1=209715&r2=209716
==============================================================================
--- team/group/security_events/main/event.c (original)
+++ team/group/security_events/main/event.c Fri Jul 31 17:02:51 2009
@@ -365,9 +365,9 @@
 	}
 
 	va_start(ap, type);
-	for (ie_type = va_arg(ap, enum ast_event_type);
+	for (ie_type = va_arg(ap, enum ast_event_ie_type);
 		ie_type != AST_EVENT_IE_END;
-		ie_type = va_arg(ap, enum ast_event_type))
+		ie_type = va_arg(ap, enum ast_event_ie_type))
 	{
 		struct ast_event_ie_val *ie_value = alloca(sizeof(*ie_value));
 		int insert = 1;
@@ -819,9 +819,9 @@
 	ast_copy_string(sub->description, description, sizeof(sub->description));
 
 	va_start(ap, userdata);
-	for (ie_type = va_arg(ap, enum ast_event_type);
+	for (ie_type = va_arg(ap, enum ast_event_ie_type);
 		ie_type != AST_EVENT_IE_END;
-		ie_type = va_arg(ap, enum ast_event_type))
+		ie_type = va_arg(ap, enum ast_event_ie_type))
 	{
 		enum ast_event_ie_pltype ie_pltype;
 
@@ -1065,7 +1065,7 @@
 {
 	va_list ap;
 	struct ast_event *event;
-	enum ast_event_type ie_type;
+	enum ast_event_ie_type ie_type;
 	struct ast_event_ie_val *ie_val;
 	AST_LIST_HEAD_NOLOCK_STATIC(ie_vals, ast_event_ie_val);
 
@@ -1077,9 +1077,9 @@
 	}
 
 	va_start(ap, type);
-	for (ie_type = va_arg(ap, enum ast_event_type);
+	for (ie_type = va_arg(ap, enum ast_event_ie_type);
 		ie_type != AST_EVENT_IE_END;
-		ie_type = va_arg(ap, enum ast_event_type))
+		ie_type = va_arg(ap, enum ast_event_ie_type))
 	{
 		struct ast_event_ie_val *ie_value = alloca(sizeof(*ie_value));
 		int insert = 1;
@@ -1218,9 +1218,9 @@
 	}
 
 	va_start(ap, type);
-	for (ie_type = va_arg(ap, enum ast_event_type);
+	for (ie_type = va_arg(ap, enum ast_event_ie_type);
 		ie_type != AST_EVENT_IE_END;
-		ie_type = va_arg(ap, enum ast_event_type))
+		ie_type = va_arg(ap, enum ast_event_ie_type))
 	{
 		enum ast_event_ie_pltype ie_pltype;
 




More information about the svn-commits mailing list