Merged revisions 167260 via svnmerge from
authorTilghman Lesher <tilghman@meg.abyt.es>
Tue, 6 Jan 2009 21:02:33 +0000 (21:02 +0000)
committerTilghman Lesher <tilghman@meg.abyt.es>
Tue, 6 Jan 2009 21:02:33 +0000 (21:02 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.4

................
  r167260 | tilghman | 2009-01-06 14:48:05 -0600 (Tue, 06 Jan 2009) | 9 lines

  Merged revisions 167259 via svnmerge from
  https://origsvn.digium.com/svn/asterisk/branches/1.2

  ........
    r167259 | tilghman | 2009-01-06 14:44:03 -0600 (Tue, 06 Jan 2009) | 2 lines

    Security fix AST-2009-001.
  ........
................

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@167265 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_iax2.c

index 98401fb..c1e3b0f 100644 (file)
@@ -241,6 +241,7 @@ static int trunkmaxsize = MAX_TRUNKDATA;
 static int authdebug = 1;
 static int autokill = 0;
 static int iaxcompat = 0;
+static int last_authmethod = 0;
 
 static int iaxdefaultdpcache=10 * 60;  /* Cache dialplan entries for 10 minutes by default */
 
@@ -7333,23 +7334,34 @@ static int registry_authrequest(int callno)
        char challenge[10];
        const char *peer_name;
        int res = -1;
+       int sentauthmethod;
 
        peer_name = ast_strdupa(iaxs[callno]->peer);
 
        /* SLD: third call to find_peer in registration */
        ast_mutex_unlock(&iaxsl[callno]);
-       p = find_peer(peer_name, 1);
+       if ((p = find_peer(peer_name, 1))) {
+               last_authmethod = p->authmethods;
+       }
+
        ast_mutex_lock(&iaxsl[callno]);
        if (!iaxs[callno])
                goto return_unref;
-       if (!p) {
+       if (!p && !delayreject) {
                ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
                goto return_unref;
        }
        
        memset(&ied, 0, sizeof(ied));
-       iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
-       if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
+       /* The selection of which delayed reject is sent may leak information,
+        * if it sets a static response.  For example, if a host is known to only
+        * use MD5 authentication, then an RSA response would indicate that the
+        * peer does not exist, and vice-versa.
+        * Therefore, we use whatever the last peer used (which may vary over the
+        * course of a server, which should leak minimal information). */
+       sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
+       iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
+       if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
                /* Build the challenge */
                snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
                ast_string_field_set(iaxs[callno], challenge, challenge);