]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
automerge commit
authorAutomerge script <automerge@asterisk.org>
Wed, 24 May 2006 04:05:45 +0000 (04:05 +0000)
committerAutomerge script <automerge@asterisk.org>
Wed, 24 May 2006 04:05:45 +0000 (04:05 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.2-netsec@29934 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_sip.c
configs/sip.conf.sample

index 12e4ad24d922c229604f92e39bfa3d5db3474f12..5ab8bec02b2590e4179b4361db3c7e23b75058c4 100644 (file)
@@ -353,6 +353,8 @@ static char default_notifymime[AST_MAX_EXTENSION] = DEFAULT_NOTIFYMIME;
 
 static int global_notifyringing = 1;   /*!< Send notifications on ringing */
 
+static int global_alwaysauthreject = 0;        /*!< Send 401 Unauthorized for all failing requests */
+
 static int default_qualify = 0;                /*!< Default Qualify= setting */
 
 static struct ast_flags global_flags = {0};            /*!< global SIP_ flags */
@@ -6515,6 +6517,15 @@ static int cb_extensionstate(char *context, char* exten, int state, void *data)
        return 0;
 }
 
+/*! \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, char *randdata, int randlen, int reliable)
+{
+       snprintf(randdata, randlen, "%08x", thread_safe_rand());
+       transmit_response_with_auth(p, "401 Unauthorized", req, randdata, reliable, "WWW-Authenticate", 0);
+}
+
 /*! \brief  register_verify: Verify registration of user */
 static int register_verify(struct sip_pvt *p, struct sockaddr_in *sin, struct sip_request *req, char *uri, int ignore)
 {
@@ -6646,8 +6657,12 @@ static int register_verify(struct sip_pvt *p, struct sockaddr_in *sin, struct si
                        transmit_response(p, "403 Authentication user name does not match account name", &p->initreq);
                        break;
                case -3:
-                       /* URI not found */
-                       transmit_response(p, "404 Not found", &p->initreq);
+                       if (global_alwaysauthreject) {
+                               transmit_fake_auth_response(p, &p->initreq, p->randdata, sizeof(p->randdata), 1);
+                       } else {
+                               /* URI not found */
+                               transmit_response(p, "404 Not found", &p->initreq);
+                       }
                        /* Set res back to -2 because we don't want to return an invalid domain message. That check already happened up above. */
                        res = -2;
                        break;
@@ -7376,10 +7391,13 @@ static int check_user_full(struct sip_pvt *p, struct sip_request *req, int sipme
                                ast_verbose("Found no matching peer or user for '%s:%d'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), p->recv.sin_addr), ntohs(p->recv.sin_port));
 
                        /* do we allow guests? */
-                       if (!global_allowguest)
-                               res = -1;  /* we don't want any guests, authentication will fail */
+                       if (!global_allowguest) {
+                               if (global_alwaysauthreject)
+                                       res = -4; /* reject with fake authorization request */
+                               else
+                                       res = -1; /* we don't want any guests, authentication will fail */
 #ifdef OSP_SUPPORT                     
-                       else if (global_allowguest == 2) {
+                       else if (global_allowguest == 2) {
                                ast_copy_flags(p, &global_flags, SIP_OSPAUTH);
                                res = check_auth(p, req, p->randdata, sizeof(p->randdata), "", "", "", sipmethod, uri, reliable, ignore); 
                        }
@@ -8352,6 +8370,7 @@ static int sip_show_settings(int fd, int argc, char *argv[])
        ast_cli(fd, "  URI user is phone no:   %s\n", ast_test_flag(&global_flags, SIP_USEREQPHONE) ? "Yes" : "No");
        ast_cli(fd, "  Our auth realm          %s\n", global_realm);
        ast_cli(fd, "  Realm. auth:            %s\n", authl ? "Yes": "No");
+       ast_cli(fd, "  Always auth rejects:    %s\n", global_alwaysauthreject ? "Yes" : "No");
        ast_cli(fd, "  User Agent:             %s\n", default_useragent);
        ast_cli(fd, "  MWI checking interval:  %d secs\n", global_mwitime);
        ast_cli(fd, "  Reg. context:           %s\n", ast_strlen_zero(regcontext) ? "(not set)" : regcontext);
@@ -10509,16 +10528,19 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
        if (!p->lastinvite && !ignore && !p->owner) {
                /* Handle authentication if this is our first invite */
                res = check_user(p, req, SIP_INVITE, e, 1, sin, ignore);
-               if (res) {
-                       if (res < 0) {
+               if (res < 0) {
+                       if (res == -4) {
+                               ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
+                               transmit_fake_auth_response(p, req, p->randdata, sizeof(p->randdata), 1);
+                       } else {
                                ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From"));
                                if (ignore)
                                        transmit_response(p, "403 Forbidden", req);
                                else
                                        transmit_response_reliable(p, "403 Forbidden", req, 1);
-                               ast_set_flag(p, SIP_NEEDDESTROY);       
-                               p->theirtag[0] = '\0'; /* Forget their to-tag, we'll get a new one */
                        }
+                       ast_set_flag(p, SIP_NEEDDESTROY);       
+                       p->theirtag[0] = '\0'; /* Forget their to-tag, we'll get a new one */
                        return 0;
                }
                /* Process the SDP portion */
@@ -10926,11 +10948,18 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req,
                }
                /* Handle authentication if this is our first subscribe */
                res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, ignore, mailbox, mailboxsize);
-               if (res) {
-                       if (res < 0) {
+               if (res < 0) {
+                       if (res == -4) {
+                               ast_log(LOG_NOTICE, "Sending fake auth rejection for user %s\n", get_header(req, "From"));
+                               transmit_fake_auth_response(p, req, p->randdata, sizeof(p->randdata), 1);
+                       } else {
                                ast_log(LOG_NOTICE, "Failed to authenticate user %s for SUBSCRIBE\n", get_header(req, "From"));
-                               ast_set_flag(p, SIP_NEEDDESTROY);       
+                               if (ignore)
+                                       transmit_response(p, "403 Forbidden", req);
+                               else
+                                       transmit_response_reliable(p, "403 Forbidden", req, 1);
                        }
+                       ast_set_flag(p, SIP_NEEDDESTROY);       
                        return 0;
                }
                gotdest = get_destination(p, NULL);
@@ -12554,6 +12583,7 @@ static int reload_config(void)
        ast_copy_string(default_useragent, DEFAULT_USERAGENT, sizeof(default_useragent));
        ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime));
        global_notifyringing = 1;
+       global_alwaysauthreject = 0;
        ast_copy_string(global_realm, DEFAULT_REALM, sizeof(global_realm));
        ast_copy_string(global_musicclass, "default", sizeof(global_musicclass));
        ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid));
@@ -12653,6 +12683,8 @@ static int reload_config(void)
                        ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime));
                } else if (!strcasecmp(v->name, "notifyringing")) {
                        global_notifyringing = ast_true(v->value);
+               } else if (!strcasecmp(v->name, "alwaysauthreject")) {
+                       global_alwaysauthreject = ast_true(v->value);
                } else if (!strcasecmp(v->name, "musicclass") || !strcasecmp(v->name, "musiconhold")) {
                        ast_copy_string(global_musicclass, v->value, sizeof(global_musicclass));
                } else if (!strcasecmp(v->name, "language")) {
index 400fbcb7e8948236f706af8aed98279c2f6e8c83..ecaef3c89bcbc0058e57ccecf4d23d4aadbdf490 100644 (file)
@@ -107,6 +107,10 @@ srvlookup=yes                      ; Enable DNS SRV lookups on outbound calls
                                ; Useful to limit subscriptions to local extensions
                                ; Settable per peer/user also
 ;notifyringing = yes           ; Notify subscriptions on RINGING state
+;alwaysauthreject = yes                ; When an incoming INVITE or REGISTER is to be rejected,
+                               ; for any reason, always reject with '401 Unauthorized'
+                               ; instead of letting the requester know whether there was
+                               ; a matching user or peer for their request
 
 ;
 ; If regcontext is specified, Asterisk will dynamically create and destroy a