[Pkg-voip-commits] r7761 - in /asterisk/branches/lenny/debian: changelog patches/r132790 patches/r171264 patches/series
paravoid at alioth.debian.org
paravoid at alioth.debian.org
Sat Nov 7 07:32:31 UTC 2009
Author: paravoid
Date: Sat Nov 7 07:32:31 2009
New Revision: 7761
URL: http://svn.debian.org/wsvn/pkg-voip/?sc=1&rev=7761
Log:
- "Remote Crash Vulnerability in SIP channel driver", AST-2009-002.
- "SIP responses expose valid usernames", AST-2009-003, CVE-2008-3903.
(Closes: #522528)
Added:
asterisk/branches/lenny/debian/patches/r132790
asterisk/branches/lenny/debian/patches/r171264
Modified:
asterisk/branches/lenny/debian/changelog
asterisk/branches/lenny/debian/patches/series
Modified: asterisk/branches/lenny/debian/changelog
URL: http://svn.debian.org/wsvn/pkg-voip/asterisk/branches/lenny/debian/changelog?rev=7761&op=diff
==============================================================================
--- asterisk/branches/lenny/debian/changelog (original)
+++ asterisk/branches/lenny/debian/changelog Sat Nov 7 07:32:31 2009
@@ -1,9 +1,12 @@
asterisk (1:1.4.21.2~dfsg-3lenny1) UNRELEASED; urgency=low
- * Multiple security fixes:
+ * Multiple security fixes:
- "Information leak in IAX2 authentication", AST-2009-001, CVE-2009-0041.
-
- -- Faidon Liambotis <paravoid at debian.org> Sat, 07 Nov 2009 09:24:00 +0200
+ - "Remote Crash Vulnerability in SIP channel driver", AST-2009-002.
+ - "SIP responses expose valid usernames", AST-2009-003, CVE-2008-3903.
+ (Closes: #522528)
+
+ -- Faidon Liambotis <paravoid at debian.org> Sat, 07 Nov 2009 09:32:07 +0200
asterisk (1:1.4.21.2~dfsg-3) unstable; urgency=medium
Added: asterisk/branches/lenny/debian/patches/r132790
URL: http://svn.debian.org/wsvn/pkg-voip/asterisk/branches/lenny/debian/patches/r132790?rev=7761&op=file
==============================================================================
--- asterisk/branches/lenny/debian/patches/r132790 (added)
+++ asterisk/branches/lenny/debian/patches/r132790 Sat Nov 7 07:32:31 2009
@@ -1,0 +1,360 @@
+Upstream r132790
+
+Allow Spiraled INVITEs to work correctly within Asterisk.
+
+Prior to this change, a spiraled INVITE would cause a 482
+Loop Detected to be sent to the caller. With this change,
+if a potential loop is detected, the Request-URI is inspected
+to see if it has changed from what was originally received. If
+pedantic mode is on, then this inspection is fully RFC 3261
+compliant. If pedantic mode is not on, then a string comparison
+is used to test the equality of the two R-URIs.
+
+This has been tested by using OpenSER to rewrite the R-URI
+and send the INVITE back to Asterisk.
+
+(closes issue #7403)
+
+--- a/channels/chan_sip.c (revision 132789)
++++ b/channels/chan_sip.c (revision 132790)
+@@ -4643,8 +4643,6 @@
+ if (!found && option_debug > 4)
+ ast_log(LOG_DEBUG, "= Being pedantic: This is not our match on request: Call ID: %s Ourtag <null> Totag %s Method %s\n", p->callid, totag, sip_methods[req->method].text);
+ }
+-
+-
+ if (found) {
+ /* Found the call */
+ ast_mutex_lock(&p->lock);
+@@ -7204,7 +7202,7 @@
+ add_header_contentLength(&req, 0);
+ }
+
+- if (!p->initreq.headers)
++ if (!p->initreq.headers || init > 2)
+ initialize_initreq(p, &req);
+ p->lastinvite = p->ocseq;
+ return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq);
+@@ -13767,7 +13765,264 @@
+ return 0;
+ }
+
++/*! \brief helper routine for sip_uri_cmp
++ *
++ * This takes the parameters from two SIP URIs and determines
++ * if the URIs match. The rules for parameters *suck*. Here's a breakdown
++ * 1. If a parameter appears in both URIs, then they must have the same value
++ * in order for the URIs to match
++ * 2. If one URI has a user, maddr, ttl, or method parameter, then the other
++ * URI must also have that parameter and must have the same value
++ * in order for the URIs to match
++ * 3. All other headers appearing in only one URI are not considered when
++ * determining if URIs match
++ *
++ * \param input1 Parameters from URI 1
++ * \param input2 Parameters from URI 2
++ * \return Return 0 if the URIs' parameters match, 1 if they do not
++ */
++static int sip_uri_params_cmp(const char *input1, const char *input2)
++{
++ char *params1 = ast_strdupa(input1);
++ char *params2 = ast_strdupa(input2);
++ char *pos1;
++ char *pos2;
++ int maddrmatch = 0;
++ int ttlmatch = 0;
++ int usermatch = 0;
++ int methodmatch = 0;
+
++ /*Quick optimization. If both params are zero-length, then
++ * they match
++ */
++ if (ast_strlen_zero(params1) && ast_strlen_zero(params2)) {
++ return 0;
++ }
++
++ pos1 = params1;
++ while (!ast_strlen_zero(pos1)) {
++ char *name1 = pos1;
++ char *value1 = strchr(pos1, '=');
++ char *semicolon1 = strchr(pos1, ';');
++ int matched = 0;
++ if (semicolon1) {
++ *semicolon1++ = '\0';
++ }
++ if (!value1) {
++ goto fail;
++ }
++ *value1++ = '\0';
++ /* Checkpoint reached. We have the name and value parsed for param1
++ * We have to duplicate params2 each time through the second loop
++ * or else we can't search and replace the semicolons with \0 each
++ * time
++ */
++ pos2 = ast_strdupa(params2);
++ while (!ast_strlen_zero(pos2)) {
++ char *name2 = pos2;
++ char *value2 = strchr(pos2, '=');
++ char *semicolon2 = strchr(pos2, ';');
++ if (semicolon2) {
++ *semicolon2++ = '\0';
++ }
++ if (!value2) {
++ goto fail;
++ }
++ if (!strcasecmp(name1, name2)) {
++ if (strcasecmp(value1, value2)) {
++ goto fail;
++ } else {
++ matched = 1;
++ break;
++ }
++ }
++ pos2 = semicolon2;
++ }
++ /* Need to see if the parameter we're looking at is one of the 'must-match' parameters */
++ if (!strcasecmp(name1, "maddr")) {
++ if (matched) {
++ maddrmatch = 1;
++ } else {
++ goto fail;
++ }
++ } else if (!strcasecmp(name1, "ttl")) {
++ if (matched) {
++ ttlmatch = 1;
++ } else {
++ goto fail;
++ }
++ } else if (!strcasecmp(name1, "user")) {
++ if (matched) {
++ usermatch = 1;
++ } else {
++ goto fail;
++ }
++ } else if (!strcasecmp(name1, "method")) {
++ if (matched) {
++ methodmatch = 1;
++ } else {
++ goto fail;
++ }
++ }
++ pos1 = semicolon1;
++ }
++
++ /* We've made it out of that horrible O(m*n) construct and there are no
++ * failures yet. We're not done yet, though, because params2 could have
++ * an maddr, ttl, user, or method header and params1 did not.
++ */
++ pos2 = params2;
++ while (!ast_strlen_zero(pos2)) {
++ char *name2 = pos2;
++ char *value2 = strchr(pos2, '=');
++ char *semicolon2 = strchr(pos2, ';');
++ if (semicolon2) {
++ *semicolon2++ = '\0';
++ }
++ if (!value2) {
++ goto fail;
++ }
++ if ((!strcasecmp(name2, "maddr") && !maddrmatch) ||
++ (!strcasecmp(name2, "ttl") && !ttlmatch) ||
++ (!strcasecmp(name2, "user") && !usermatch) ||
++ (!strcasecmp(name2, "method") && !methodmatch)) {
++ goto fail;
++ }
++ }
++ return 0;
++
++fail:
++ return 1;
++}
++
++/*! \brief helper routine for sip_uri_cmp
++ *
++ * This takes the "headers" from two SIP URIs and determines
++ * if the URIs match. The rules for headers is simple. If a header
++ * appears in one URI, then it must also appear in the other URI. The
++ * order in which the headers appear does not matter.
++ *
++ * \param input1 Headers from URI 1
++ * \param input2 Headers from URI 2
++ * \return Return 0 if the URIs' headers match, 1 if they do not
++ */
++static int sip_uri_headers_cmp(const char *input1, const char *input2)
++{
++ char *headers1 = ast_strdupa(input1);
++ char *headers2 = ast_strdupa(input2);
++ int zerolength1 = ast_strlen_zero(headers1);
++ int zerolength2 = ast_strlen_zero(headers2);
++ int different = 0;
++ char *header1;
++
++ if ((zerolength1 && !zerolength2) ||
++ (zerolength2 && !zerolength1))
++ return 1;
++
++ if (zerolength1 && zerolength2)
++ return 0;
++
++ /* At this point, we can definitively state that both inputs are
++ * not zero-length. First, one more optimization. If the length
++ * of the headers is not equal, then we definitely have no match
++ */
++ if (strlen(headers1) != strlen(headers2)) {
++ return 1;
++ }
++
++ for (header1 = strsep(&headers1, "&"); header1; header1 = strsep(&headers1, "&")) {
++ if (!strcasestr(headers2, header1)) {
++ different = 1;
++ break;
++ }
++ }
++
++ return different;
++}
++
++static int sip_uri_cmp(const char *input1, const char *input2)
++{
++ char *uri1 = ast_strdupa(input1);
++ char *uri2 = ast_strdupa(input2);
++ char *host1;
++ char *host2;
++ char *params1;
++ char *params2;
++ char *headers1;
++ char *headers2;
++
++ /* Strip off "sip:" from the URI. We know this is present
++ * because it was checked back in parse_request()
++ */
++ strsep(&uri1, ":");
++ strsep(&uri2, ":");
++
++ if ((host1 = strchr(uri1, '@'))) {
++ *host1++ = '\0';
++ }
++ if ((host2 = strchr(uri2, '@'))) {
++ *host2++ = '\0';
++ }
++
++ /* Check for mismatched username and passwords. This is the
++ * only case-sensitive comparison of a SIP URI
++ */
++ if ((host1 && !host2) ||
++ (host2 && !host1) ||
++ (host1 && host2 && strcmp(uri1, uri2))) {
++ return 1;
++ }
++
++ if (!host1)
++ host1 = uri1;
++ if (!host2)
++ host2 = uri2;
++
++ /* Strip off the parameters and headers so we can compare
++ * host and port
++ */
++
++ if ((params1 = strchr(host1, ';'))) {
++ *params1++ = '\0';
++ }
++ if ((params2 = strchr(host2, ';'))) {
++ *params2++ = '\0';
++ }
++
++ /* Headers come after parameters, but there may be headers without
++ * parameters, thus the S_OR
++ */
++ if ((headers1 = strchr(S_OR(params1, host1), '?'))) {
++ *headers1++ = '\0';
++ }
++ if ((headers2 = strchr(S_OR(params2, host2), '?'))) {
++ *headers2++ = '\0';
++ }
++
++ /* Now the host/port are properly isolated. We can get by with a string comparison
++ * because the SIP URI checking rules have some interesting exceptions that make
++ * this possible. I will note 2 in particular
++ * 1. hostnames which resolve to the same IP address as well as a hostname and its
++ * IP address are not considered a match with SIP URI's.
++ * 2. If one URI specifies a port and the other does not, then the URIs do not match.
++ * This includes if one URI explicitly contains port 5060 and the other implies it
++ * by not having a port specified.
++ */
++
++ if (strcasecmp(host1, host2)) {
++ return 1;
++ }
++
++ /* Headers have easier rules to follow, so do those first */
++ if (sip_uri_headers_cmp(headers1, headers2)) {
++ return 1;
++ }
++
++ /* And now the parameters. Ugh */
++ return sip_uri_params_cmp(params1, params2);
++}
++
++
+ /*! \brief Handle incoming INVITE request
+ \note If the INVITE has a Replaces header, it is part of an
+ * attended transfer. If so, we do not go through the dial
+@@ -13814,10 +14069,44 @@
+ being able to call yourself */
+ /* If pedantic is on, we need to check the tags. If they're different, this is
+ in fact a forked call through a SIP proxy somewhere. */
+- transmit_response(p, "482 Loop Detected", req);
+- p->invitestate = INV_COMPLETED;
+- sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
+- return 0;
++ int different;
++ if (pedanticsipchecking)
++ different = sip_uri_cmp(p->initreq.rlPart2, req->rlPart2);
++ else
++ different = strcmp(p->initreq.rlPart2, req->rlPart2);
++ if (!different) {
++ transmit_response(p, "482 Loop Detected", req);
++ p->invitestate = INV_COMPLETED;
++ sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
++ return 0;
++ } else {
++ /* This is a spiral. What we need to do is to just change the outgoing INVITE
++ * so that it now routes to the new Request URI. Since we created the INVITE ourselves
++ * that should be all we need to do.
++ */
++ char *uri = ast_strdupa(req->rlPart2);
++ char *at = strchr(uri, '@');
++ char *peerorhost;
++ struct sip_pkt *pkt = NULL;
++ if (option_debug > 2) {
++ ast_log(LOG_DEBUG, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", p->initreq.rlPart2, req->rlPart2);
++ }
++ if (at) {
++ *at = '\0';
++ }
++ /* Parse out "sip:" */
++ if ((peerorhost = strchr(uri, ':'))) {
++ *peerorhost++ = '\0';
++ }
++ create_addr(p, peerorhost);
++ ast_string_field_free(p, theirtag);
++ for (pkt = p->packets; pkt; pkt = pkt->next) {
++ if (pkt->seqno == p->icseq && pkt->method == SIP_INVITE) {
++ AST_SCHED_DEL(sched, pkt->retransid);
++ }
++ }
++ return transmit_invite(p, SIP_INVITE, 1, 3);
++ }
+ }
+
+ if (!ast_test_flag(req, SIP_PKT_IGNORE) && p->pendinginvite) {
+@@ -15332,7 +15621,7 @@
+ if (!p->initreq.headers) {
+ if (option_debug)
+ ast_log(LOG_DEBUG, "That's odd... Got a response on a call we dont know about. Cseq %d Cmd %s\n", seqno, cmd);
+- ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
++ ast_set_flag(&p->flags[0], SIP_NEEDDESTROY);
+ return 0;
+ } else if (p->ocseq && (p->ocseq < seqno) && (seqno != p->lastnoninvite)) {
+ if (option_debug)
Added: asterisk/branches/lenny/debian/patches/r171264
URL: http://svn.debian.org/wsvn/pkg-voip/asterisk/branches/lenny/debian/patches/r171264?rev=7761&op=file
==============================================================================
--- asterisk/branches/lenny/debian/patches/r171264 (added)
+++ asterisk/branches/lenny/debian/patches/r171264 Sat Nov 7 07:32:31 2009
@@ -1,0 +1,53 @@
+Upstream r171264
+
+Don't retransmit 401 on REGISTER requests when alwaysauthreject=yes
+
+(closes issue #14284)
+
+--- a/channels/chan_sip.c (revision 171263)
++++ b/channels/chan_sip.c (revision 171264)
+@@ -1264,7 +1264,7 @@
+ static int transmit_response_with_unsupported(struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported);
+ static int transmit_response_with_auth(struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *rand, enum xmittype reliable, const char *header, int stale);
+ static int transmit_response_with_allow(struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable);
+-static void transmit_fake_auth_response(struct sip_pvt *p, struct sip_request *req, int reliable);
++static void transmit_fake_auth_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable);
+ static int transmit_request(struct sip_pvt *p, int sipmethod, int inc, enum xmittype reliable, int newbranch);
+ static int transmit_request_with_auth(struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch);
+ static int transmit_invite(struct sip_pvt *p, int sipmethod, int sdp, int init);
+@@ -8774,7 +8774,7 @@
+ /*! \brief Send a fake 401 Unauthorized response when the administrator
+ wants to hide the names of local users/peers from fishers
+ */
+-static void transmit_fake_auth_response(struct sip_pvt *p, struct sip_request *req, int reliable)
++static void transmit_fake_auth_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable)
+ {
+ ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */
+ transmit_response_with_auth(p, "401 Unauthorized", req, p->randdata, reliable, "WWW-Authenticate", 0);
+@@ -8931,7 +8931,7 @@
+ case AUTH_PEER_NOT_DYNAMIC:
+ case AUTH_ACL_FAILED:
+ if (global_alwaysauthreject) {
+- transmit_fake_auth_response(p, &p->initreq, 1);
++ transmit_fake_auth_response(p, &p->initreq, XMIT_UNRELIABLE);
+ } else {
+ /* URI not found */
+ if (res == AUTH_PEER_NOT_DYNAMIC)
+@@ -14421,7 +14421,7 @@
+ if (res < 0) { /* Something failed in authentication */
+ if (res == AUTH_FAKE_AUTH) {
+ ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
+- transmit_fake_auth_response(p, req, 1);
++ transmit_fake_auth_response(p, req, XMIT_RELIABLE);
+ } else {
+ ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From"));
+ transmit_response_reliable(p, "403 Forbidden", req);
+@@ -15458,7 +15458,7 @@
+ if (res < 0) {
+ if (res == AUTH_FAKE_AUTH) {
+ ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
+- transmit_fake_auth_response(p, req, 1);
++ transmit_fake_auth_response(p, req, XMIT_UNRELIABLE);
+ } else {
+ ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From"));
+ transmit_response_reliable(p, "403 Forbidden", req);
Modified: asterisk/branches/lenny/debian/patches/series
URL: http://svn.debian.org/wsvn/pkg-voip/asterisk/branches/lenny/debian/patches/series?rev=7761&op=diff
==============================================================================
--- asterisk/branches/lenny/debian/patches/series (original)
+++ asterisk/branches/lenny/debian/patches/series Sat Nov 7 07:32:31 2009
@@ -90,3 +90,9 @@
### lenny fixes
AST-2009-001
+
+r132790
+AST-2009-002
+
+r171264
+AST-2009-003
More information about the Pkg-voip-commits
mailing list