Update of /usr/cvsroot/asterisk/channels
In directory mongoose.digium.com:/tmp/cvs-serv22780/channels

Modified Files:
        chan_sip.c 
Log Message:
preserve user-added headers when outbound INVITE must be authenticated (issue 
#5070)


Index: chan_sip.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v
retrieving revision 1.830
retrieving revision 1.831
diff -u -d -r1.830 -r1.831
--- chan_sip.c  30 Aug 2005 21:34:41 -0000      1.830
+++ chan_sip.c  30 Aug 2005 21:59:01 -0000      1.831
@@ -628,6 +628,7 @@
        struct sip_history *history;            /* History of this SIP dialog */
        struct ast_variable *chanvars;          /* Channel variables to set for 
call */
        struct sip_pvt *next;                   /* Next call in chain */
+       struct sip_invite_param *options;       /* Options for INVITE */
 } *iflist = NULL;
 
 #define FLAG_RESPONSE (1 << 0)
@@ -825,7 +826,7 @@
 static int transmit_response_with_auth(struct sip_pvt *p, char *msg, struct 
sip_request *req, char *rand, int reliable, char *header, int stale);
 static int transmit_request(struct sip_pvt *p, int sipmethod, int inc, int 
reliable, int newbranch);
 static int transmit_request_with_auth(struct sip_pvt *p, int sipmethod, int 
inc, int reliable, int newbranch);
-static int transmit_invite(struct sip_pvt *p, int sipmethod, int sendsdp, 
struct sip_invite_param *options, int init);
+static int transmit_invite(struct sip_pvt *p, int sipmethod, int sendsdp, int 
init);
 static int transmit_reinvite_with_sdp(struct sip_pvt *p);
 static int transmit_info_with_digit(struct sip_pvt *p, char digit);
 static int transmit_info_with_vidupdate(struct sip_pvt *p);
@@ -1922,34 +1923,35 @@
 #endif 
        struct varshead *headp;
        struct ast_var_t *current;
-       struct sip_invite_param options;
+       
 
-       memset(&options, 0, sizeof(struct sip_invite_param));
        
        p = ast->tech_pvt;
        if ((ast->_state != AST_STATE_DOWN) && (ast->_state != 
AST_STATE_RESERVED)) {
                ast_log(LOG_WARNING, "sip_call called on %s, neither down nor 
reserved\n", ast->name);
                return -1;
        }
+
+
        /* Check whether there is vxml_url, distinctive ring variables */
 
        headp=&ast->varshead;
        AST_LIST_TRAVERSE(headp,current,entries) {
                /* Check whether there is a VXML_URL variable */
-               if (!options.vxml_url && 
!strcasecmp(ast_var_name(current),"VXML_URL")) {
-                       options.vxml_url = ast_var_value(current);
-               } else if (!options.distinctive_ring && 
!strcasecmp(ast_var_name(current),"ALERT_INFO")) {
+               if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), 
"VXML_URL")) {
+                       p->options->vxml_url = ast_var_value(current);
+               } else if (!p->options->distinctive_ring && 
!strcasecmp(ast_var_name(current), "ALERT_INFO")) {
                        /* Check whether there is a ALERT_INFO variable */
-                       options.distinctive_ring = ast_var_value(current);
-               } else if (!options.addsipheaders && 
!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
+                       p->options->distinctive_ring = ast_var_value(current);
+               } else if (!p->options->addsipheaders && 
!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
                        /* Check whether there is a variable with a name 
starting with SIPADDHEADER */
-                       options.addsipheaders = 1;
+                       p->options->addsipheaders = 1;
                }
 
                
 #ifdef OSP_SUPPORT
-               else if (!options.osptoken && 
!strcasecmp(ast_var_name(current), "OSPTOKEN")) {
-                       options.osptoken = ast_var_value(current);
+               else if (!p->options->osptoken && 
!strcasecmp(ast_var_name(current), "OSPTOKEN")) {
+                       p->options->osptoken = ast_var_value(current);
                } else if (!osphandle && !strcasecmp(ast_var_name(current), 
"OSPHANDLE")) {
                        osphandle = ast_var_value(current);
                }
@@ -1959,10 +1961,10 @@
        res = 0;
        ast_set_flag(p, SIP_OUTGOING);
 #ifdef OSP_SUPPORT
-       if (!options.osptoken || !osphandle || (sscanf(osphandle, "%d", 
&p->osphandle) != 1)) {
+       if (!p->options->osptoken || !osphandle || (sscanf(osphandle, "%d", 
&p->osphandle) != 1)) {
                /* Force Disable OSP support */
-               ast_log(LOG_DEBUG, "Disabling OSP support for this call. 
osptoken = %s, osphandle = %s\n", options.osptoken, osphandle);
-               options.osptoken = NULL;
+               ast_log(LOG_DEBUG, "Disabling OSP support for this call. 
osptoken = %s, osphandle = %s\n", p->options->osptoken, osphandle);
+               p->options->osptoken = NULL;
                osphandle = NULL;
                p->osphandle = -1;
        }
@@ -1972,7 +1974,7 @@
        if ( res != -1 ) {
                p->callingpres = ast->cid.cid_pres;
                p->jointcapability = p->capability;
-               transmit_invite(p, SIP_INVITE, 1, &options, 1);
+               transmit_invite(p, SIP_INVITE, 1, 1);
                if (p->maxtime) {
                        /* Initialize auto-congest time */
                        p->initid = ast_sched_add(sched, p->maxtime * 4, 
auto_congest, p);
@@ -2014,6 +2016,9 @@
        if (dumphistory)
                sip_dump_history(p);
 
+       if (p->options)
+               free(p->options);
+
        if (p->stateid > -1)
                ast_extension_state_del(p->stateid, NULL);
        if (p->initid > -1)
@@ -4503,7 +4508,7 @@
 }
 
 /*--- transmit_invite: Build REFER/INVITE/OPTIONS message and transmit it ---*/
-static int transmit_invite(struct sip_pvt *p, int sipmethod, int sdp, struct 
sip_invite_param *options, int init)
+static int transmit_invite(struct sip_pvt *p, int sipmethod, int sdp, int init)
 {
        struct sip_request req;
        
@@ -4512,12 +4517,12 @@
                /* Bump branch even on initial requests */
                p->branch ^= rand();
                build_via(p, p->via, sizeof(p->via));
-               initreqprep(&req, p, sipmethod, options ? options->vxml_url : 
(char *) NULL);
+               initreqprep(&req, p, sipmethod, p->options ? 
p->options->vxml_url : (char *) NULL);
        } else
                reqprep(&req, p, sipmethod, 0, 1);
                
-       if (options && options->auth)
-               add_header(&req, options->authheader, options->auth);
+       if (p->options && p->options->auth)
+               add_header(&req, p->options->authheader, p->options->auth);
        append_date(&req);
        if (sipmethod == SIP_REFER) {   /* Call transfer */
                if (!ast_strlen_zero(p->refer_to))
@@ -4526,19 +4531,19 @@
                        add_header(&req, "Referred-By", p->referred_by);
        }
 #ifdef OSP_SUPPORT
-       if (options && options->osptoken && 
!ast_strlen_zero(options->osptoken)) {
-               ast_log(LOG_DEBUG,"Adding OSP Token: %s\n", options->osptoken);
-               add_header(&req, "P-OSP-Auth-Token", options->osptoken);
+       if (p->options && p->options->osptoken && 
!ast_strlen_zero(p->options->osptoken)) {
+               ast_log(LOG_DEBUG,"Adding OSP Token: %s\n", 
p->options->osptoken);
+               add_header(&req, "P-OSP-Auth-Token", p->options->osptoken);
        } else {
                ast_log(LOG_DEBUG,"NOT Adding OSP Token\n");
        }
 #endif
-       if (options && options->distinctive_ring && 
!ast_strlen_zero(options->distinctive_ring))
+       if (p->options && p->options->distinctive_ring && 
!ast_strlen_zero(p->options->distinctive_ring))
        {
-               add_header(&req, "Alert-Info", options->distinctive_ring);
+               add_header(&req, "Alert-Info", p->options->distinctive_ring);
        }
        add_header(&req, "Allow", ALLOWED_METHODS);
-       if (options && options->addsipheaders && init) {
+       if (p->options && p->options->addsipheaders ) {
                struct ast_channel *ast;
                char *header = (char *) NULL;
                char *content = (char *) NULL;
@@ -4548,18 +4553,20 @@
 
                ast = p->owner; /* The owner channel */
                if (ast) {
-                       headp=&ast->varshead;
+                       char *headdup;
+                       headp = &ast->varshead;
                        if (!headp)
                                ast_log(LOG_WARNING,"No Headp for the 
channel...ooops!\n");
                        else {
-                               AST_LIST_TRAVERSE(headp,current,entries) {  
+                               AST_LIST_TRAVERSE(headp, current, entries) {  
                                        /* SIPADDHEADER: Add SIP header to 
outgoing call        */
-                                       if 
(!strncasecmp(ast_var_name(current),"SIPADDHEADER",strlen("SIPADDHEADER"))) {
+                                       if (!strncasecmp(ast_var_name(current), 
"SIPADDHEADER", strlen("SIPADDHEADER"))) {
                                                header = ast_var_value(current);
+                                               headdup = ast_strdupa(header);
                                                /* Strip of the starting " (if 
it's there) */
-                                               if (*header == '"')
-                                                       header++;
-                                               if ((content = strchr(header, 
':'))) {
+                                               if (*headdup == '"')
+                                                       headdup++;
+                                               if ((content = strchr(headdup, 
':'))) {
                                                        *content = '\0';
                                                        content++;      /* Move 
pointer ahead */
                                                        /* Skip white space */
@@ -4570,9 +4577,9 @@
                                                        if (*end == '"')
                                                                *end = '\0';
                                                
-                                                       add_header(&req, 
header, content);
+                                                       add_header(&req, 
headdup, content);
                                                        if (sipdebug)
-                                                               
ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", header, 
content);
+                                                               
ast_log(LOG_DEBUG, "Adding SIP Header \"%s\" with content :%s: \n", headdup, 
content);
                                                }
                                        }
                                }
@@ -8343,21 +8350,27 @@
 static int do_proxy_auth(struct sip_pvt *p, struct sip_request *req, char 
*header, char *respheader, int sipmethod, int init) 
 {
        char digest[1024];
-       struct sip_invite_param options;
 
-       memset(&options, 0, sizeof(struct sip_invite_param));
+       if (!p->options) {
+               p->options = calloc(1, sizeof(*p->options));
+               if (!p->options) {
+                       ast_log(LOG_ERROR, "Out of memory\n");
+                       return -2;
+               }
+       }
+
        p->authtries++;
        if (option_debug > 1)
                ast_log(LOG_DEBUG, "Auth attempt %d on %s\n", p->authtries, 
sip_methods[sipmethod].text);
-       memset(digest,0,sizeof(digest));
+       memset(digest, 0, sizeof(digest));
        if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) {
                /* No way to authenticate */
                return -1;
        }
        /* Now we have a reply digest */
-       options.auth = digest;
-       options.authheader = respheader;
-       return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, &options, 
init); 
+       p->options->auth = digest;
+       p->options->authheader = respheader;
+       return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 
 }
 
 /*--- reply_digest: reply to authentication for outbound registrations ---*/
@@ -10629,9 +10642,9 @@
        ast_set_flag(p, SIP_OUTGOING);
 #ifdef VOCAL_DATA_HACK
        ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", 
sizeof(p->username));
-       transmit_invite(p, SIP_INVITE, 0, NULL, 1);
+       transmit_invite(p, SIP_INVITE, 0, 1);
 #else
-       transmit_invite(p, SIP_OPTIONS, 0, NULL, 1);
+       transmit_invite(p, SIP_OPTIONS, 0, 1);
 #endif
        gettimeofday(&peer->ps, NULL);
        peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, 
sip_poke_noanswer, peer);
@@ -10722,6 +10735,12 @@
                return NULL;
        }
 
+       p->options = calloc(1, sizeof(*p->options));
+       if (!p->options) {
+               ast_log(LOG_ERROR, "Out of memory\n");
+               return NULL;
+       }
+
        ast_copy_string(tmp, dest, sizeof(tmp));
        host = strchr(tmp, '@');
        if (host) {

_______________________________________________
Asterisk-Cvs mailing list
[email protected]
http://lists.digium.com/mailman/listinfo/asterisk-cvs

Reply via email to