[Pkg-voip-commits] r7002 - in /asterisk/branches/lenny/debian: changelog patches/AST-2009-003 patches/series
tzafrir-guest at alioth.debian.org
tzafrir-guest at alioth.debian.org
Wed Apr 15 09:52:40 UTC 2009
Author: tzafrir-guest
Date: Wed Apr 15 09:52:40 2009
New Revision: 7002
URL: http://svn.debian.org/wsvn/pkg-voip/?sc=1&rev=7002
Log:
Patch AST-2009-003 (CVE-2008-3903) - SIP responses expose valid usernames
(Closes: #522528).
Added:
asterisk/branches/lenny/debian/patches/AST-2009-003
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=7002&op=diff
==============================================================================
--- asterisk/branches/lenny/debian/changelog (original)
+++ asterisk/branches/lenny/debian/changelog Wed Apr 15 09:52:40 2009
@@ -6,8 +6,10 @@
* Patch fix_fxo_alarm: Fix Zaptel FXO alarm detection on startup
(Closes: #516838).
* Properly clean h323, as disclean doesn't.
-
- -- Tzafrir Cohen <tzafrir.cohen at xorcom.com> Sat, 21 Feb 2009 16:08:59 +0200
+ * Patch AST-2009-003 (CVE-2008-3903) - SIP responses expose valid usernames
+ (Closes: #522528).
+
+ -- Tzafrir Cohen <tzafrir.cohen at xorcom.com> Sun, 05 Apr 2009 00:38:53 +0300
asterisk (1:1.4.21.2~dfsg-3) unstable; urgency=medium
Added: asterisk/branches/lenny/debian/patches/AST-2009-003
URL: http://svn.debian.org/wsvn/pkg-voip/asterisk/branches/lenny/debian/patches/AST-2009-003?rev=7002&op=file
==============================================================================
--- asterisk/branches/lenny/debian/patches/AST-2009-003 (added)
+++ asterisk/branches/lenny/debian/patches/AST-2009-003 Wed Apr 15 09:52:40 2009
@@ -1,0 +1,182 @@
+Fix for AST-2009-003 (CVE-2008-3903) - SIP responses expose valid usernames
+
+From: http://downloads.digium.com/pub/security/AST-2009-003-1.4.diff
+
+--- a/channels/chan_sip.c
++++ b/channels/chan_sip.c
+@@ -1247,7 +1247,7 @@ static int transmit_response_with_sdp(st
+ 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, int sipmethod, struct sip_request *req, int 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);
+@@ -8642,10 +8642,96 @@ static int cb_extensionstate(char *conte
+ /*! \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, int sipmethod, struct sip_request *req, int 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);
++ /* We have to emulate EXACTLY what we'd get with a good peer
++ * and a bad password, or else we leak information. */
++ const char *response = "407 Proxy Authentication Required";
++ const char *reqheader = "Proxy-Authorization";
++ const char *respheader = "Proxy-Authenticate";
++ const char *authtoken;
++ struct ast_dynamic_str *buf;
++ char *c;
++
++ /* table of recognised keywords, and their value in the digest */
++ enum keys { K_NONCE, K_LAST };
++ struct x {
++ const char *key;
++ const char *s;
++ } *i, keys[] = {
++ [K_NONCE] = { "nonce=", "" },
++ [K_LAST] = { NULL, NULL}
++ };
++
++ if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) {
++ response = "401 Unauthorized";
++ reqheader = "Authorization";
++ respheader = "WWW-Authenticate";
++ }
++ authtoken = get_header(req, reqheader);
++ if (ast_test_flag(req, SIP_PKT_IGNORE) && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
++ /* This is a retransmitted invite/register/etc, don't reconstruct authentication
++ * information */
++ transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0);
++ /* Schedule auto destroy in 32 seconds (according to RFC 3261) */
++ sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
++ return;
++ } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
++ /* We have no auth, so issue challenge and request authentication */
++ ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */
++ transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0);
++ /* Schedule auto destroy in 32 seconds */
++ sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
++ return;
++ }
++
++ if (!(buf = ast_dynamic_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) {
++ transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
++ return;
++ }
++
++ /* Make a copy of the response and parse it */
++ if (ast_dynamic_str_thread_set(&buf, 0, &check_auth_buf, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) {
++ transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
++ return;
++ }
++
++ c = buf->str;
++
++ while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */
++ for (i = keys; i->key != NULL; i++) {
++ const char *separator = ","; /* default */
++
++ if (strncasecmp(c, i->key, strlen(i->key)) != 0) {
++ continue;
++ }
++ /* Found. Skip keyword, take text in quotes or up to the separator. */
++ c += strlen(i->key);
++ if (*c == '"') { /* in quotes. Skip first and look for last */
++ c++;
++ separator = "\"";
++ }
++ i->s = c;
++ strsep(&c, separator);
++ break;
++ }
++ if (i->key == NULL) { /* not found, jump after space or comma */
++ strsep(&c, " ,");
++ }
++ }
++
++ /* Verify nonce from request matches our nonce. If not, send 401 with new nonce */
++ if (strcasecmp(p->randdata, keys[K_NONCE].s)) {
++ if (!ast_test_flag(req, SIP_PKT_IGNORE)) {
++ ast_string_field_build(p, randdata, "%08lx", ast_random());
++ }
++ transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE);
++
++ /* Schedule auto destroy in 32 seconds */
++ sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
++ } else {
++ transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
++ }
+ }
+
+ /*! \brief Verify registration of user
+@@ -8779,6 +8865,14 @@ static enum check_auth_result register_v
+ }
+ }
+ }
++ if (!peer && global_alwaysauthreject) {
++ /* If we found a peer, we transmit a 100 Trying. Therefore, if we're
++ * trying to avoid leaking information, we MUST also transmit the same
++ * response when we DON'T find a peer. */
++ transmit_response(p, "100 Trying", req);
++ /* Insert a fake delay between the 100 and the subsequent failure. */
++ sched_yield();
++ }
+ if (!res) {
+ ast_device_state_changed("SIP/%s", peer->name);
+ }
+@@ -8789,7 +8883,7 @@ static enum check_auth_result register_v
+ transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
+ break;
+ case AUTH_USERNAME_MISMATCH:
+- /* Username and digest username does not match.
++ /* Username and digest username does not match.
+ Asterisk uses the From: username for authentication. We need the
+ users to use the same authentication user name until we support
+ proper authentication by digest auth name */
+@@ -8799,7 +8893,7 @@ static enum check_auth_result register_v
+ 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, SIP_REGISTER, &p->initreq, 1);
+ } else {
+ /* URI not found */
+ if (res == AUTH_PEER_NOT_DYNAMIC)
+@@ -13966,7 +14060,7 @@ static int handle_request_invite(struct
+ 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, SIP_INVITE, req, 1);
+ } else {
+ ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From"));
+ transmit_response_reliable(p, "403 Forbidden", req);
+@@ -14992,7 +15086,7 @@ static int handle_request_subscribe(stru
+ 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, SIP_SUBSCRIBE, req, 1);
+ } else {
+ ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From"));
+ transmit_response_reliable(p, "403 Forbidden", req);
+--- a/configs/sip.conf.sample
++++ b/configs/sip.conf.sample
+@@ -126,9 +126,11 @@ srvlookup=yes ; Enable DNS SRV lookups
+ ;callevents=no ; generate manager events when sip ua
+ ; performs events (e.g. hold)
+ ;alwaysauthreject = yes ; When an incoming INVITE or REGISTER is to be rejected,
+- ; for any reason, always reject with '401 Unauthorized'
++ ; for any reason, always reject with an identical response
++ ; equivalent to valid username and invalid password/hash
+ ; instead of letting the requester know whether there was
+- ; a matching user or peer for their request
++ ; a matching user or peer for their request. This reduces
++ ; the ability of an attacker to scan for valid SIP usernames.
+
+ ;g726nonstandard = yes ; If the peer negotiates G726-32 audio, use AAL2 packing
+ ; order instead of RFC3551 packing order (this is required
Modified: asterisk/branches/lenny/debian/patches/series
URL: http://svn.debian.org/wsvn/pkg-voip/asterisk/branches/lenny/debian/patches/series?rev=7002&op=diff
==============================================================================
--- asterisk/branches/lenny/debian/patches/series (original)
+++ asterisk/branches/lenny/debian/patches/series Wed Apr 15 09:52:40 2009
@@ -1,5 +1,6 @@
# Some simple security fixes:
AST-2009-001
+AST-2009-003
### upstream fixes
allow-tilde-destdir
More information about the Pkg-voip-commits
mailing list