[Home]

Summary:ASTERISK-00257: [patch] Asterisk doesn't respond to 407 for REFER
Reporter:linxu01 (linxu01)Labels:
Date Opened:2003-09-12 08:21:53Date Closed:2004-09-25 02:53:48
Priority:MajorRegression?No
Status:Closed/CompleteComponents:Core/General
Versions:Frequency of
Occurrence
Related
Issues:
Environment:Attachments:( 0) refer407.txt
Description:This is similar to bugASTERISK-127, which has been fixed. Basically when * transfers an incoming call from a SIP proxy back to the same SIP proxy (on a different number), the REFER it sent to proxy is challenged with a 407 and it doesn't know how to handle it. I attached a patch for this.

Index: channels/chan_sip.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v
retrieving revision 1.176
diff -u -r1.176 chan_sip.c
--- channels/chan_sip.c 11 Sep 2003 22:41:30 -0000      1.176
+++ channels/chan_sip.c 12 Sep 2003 13:20:16 -0000
@@ -386,7 +386,7 @@
static int transmit_reinvite_with_sdp(struct sip_pvt *p, struct ast_rtp *rtp, struct ast_rtp *vrtp);
static int transmit_info_with_digit(struct sip_pvt *p, char digit);
static int transmit_message_with_text(struct sip_pvt *p, char *text);
-static int transmit_refer(struct sip_pvt *p, char *dest);
+static int transmit_refer(struct sip_pvt *p, char *dest, char *auth);
static int do_proxy_auth(struct sip_pvt *p, struct sip_request *req, char *msg, int init);
static char *getsipuri(char *header);
static void free_old_route(struct sip_route *route);
@@ -1126,7 +1126,7 @@
{
       struct sip_pvt *p = ast->pvt->pvt;
       int res;
-       res = transmit_refer(p, dest);
+       res = transmit_refer(p, dest, NULL);
       return res;
}

@@ -2956,7 +2956,7 @@
       return send_request(p, &req, 1, p->ocseq);
}

-static int transmit_refer(struct sip_pvt *p, char *dest)
+static int transmit_refer(struct sip_pvt *p, char *dest, char * auth)
{
       struct sip_request req;
       char from[256];
@@ -2983,10 +2983,16 @@
       } else {
               snprintf(referto, sizeof(referto), "<sip:%s>", dest);
       }
+
+       /* save referto */
+       if (!strlen(p->refer_to))
+               strncpy(p->refer_to, dest, sizeof(p->refer_to));

       reqprep(&req, p, "REFER", 0);
       add_header(&req, "Refer-To", referto);
       add_header(&req, "Referred-By", callerid);
+       if (auth)
+               add_header(&req, "Proxy-Authorization", auth);
       return send_request(p, &req, 1, p->ocseq);
}

@@ -4189,7 +4195,10 @@
               /* No way to authenticate */
               return -1;
       }
-       return transmit_invite(p,msg,!strcasecmp(msg, "INVITE"),digest, NULL,NULL, init);
+       if (!strcasecmp(msg, "REFER"))
+               return transmit_refer(p,p->refer_to,digest);
+       else
+               return transmit_invite(p,msg,!strcasecmp(msg, "INVITE"),digest, NULL,NULL, init);
}

static int reply_digest(struct sip_pvt *p, struct sip_request *req, char *header, char *orig_header, char *digest, int digest_len) {
@@ -4617,12 +4626,12 @@
                               transmit_request(p, "ACK", seqno, 0);
                       break;
               case 407:
-                       if (!strcasecmp(msg, "BYE")) {
+                       if (!strcasecmp(msg, "BYE") || !strcasecmp(msg, "REFER")) {
                               if (!strlen(p->peername))
-                                       ast_log(LOG_WARNING, "Asked to authenticate BYE, to %s:%d but we have no matching peer!\n",
-                                                       inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
-                               if ((p->authtries > 1) || do_proxy_auth(p, req, "BYE", 0)) {
-                                       ast_log(LOG_NOTICE, "Failed to authenticate on BYE to '%s'\n", get_header(&p->initreq, "From"));
+                                       ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n",
+                                       msg,            inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
+                               if ((p->authtries > 1) || do_proxy_auth(p, req, msg, 0)) {
+                                       ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
                                       p->needdestroy = 1;
                               }
                       }
Comments:By: John Todd (jtodd) 2003-10-19 20:24:33

Apparently the current CVS has changed too much to allow this to patch easily.  Can you please re-submit this patch against the current CVS, and also submit as an attached file instead of in-line notes?  Thanks!  I think this is a very useful patch, and somehow it's been overlooked, so let's see if we can't get it tested and added to the current tree.

By: linxu01 (linxu01) 2003-10-20 07:58:30

OK. Give me a few days since I haven't followed * for a while...

By: John Todd (jtodd) 2003-10-26 12:29:00.000-0600

Linxu01 - Sorry to be a pest, but we have another patch for 407 issues waiting in the wings, and I want to ensure that these two patches don't step on each other's toes.  Can you update this and re-submit (as a diff -u file attachment) and then I'll have the next author try to patch around your patches...  I am uncertain if these two will even conflict, but I'd prefer to get them layered on over each other instead of in parallel.

By: linxu01 (linxu01) 2003-10-26 15:12:05.000-0600

My previous patch is not working any more. Also my test environment also changed. It may take a while for me to work on this again. If you want you can check in your other patch first and I can do some tests to see if it works.

By: wire (wire) 2003-11-25 10:57:35.000-0600

I've attached a patch to chan_sip.c to handle 407 challenge on REFER.

One thing I noticed is build_reply_digest() uses sip_pvt.peername as the digest username instead of sip_pvt.username. I guess because when sending REGISTER it copies either sip_registry.authuser or sip_registry.username into sip_pvt.peername, (see transmit_register()) so REGISTER expects to use peername as the username. Maybe transmit_register should copy username/authuser into sip_pvt.username and build_reply_digest should use username instead of peername

I didn't make that change for fear of breaking something else, my workaround was to change my sip.conf to use the username as the peername, e.g.:

register => 17329999999:passwd@sip.host.net:12345/7777

[17329999999]
type=peer
username=17329999999
secret=passwd
host=sip.host.net
insecure=yes

edited on: 11-25-03 10:51

By: Olle Johansson (oej) 2004-03-21 08:58:06.000-0600

Is this still an open case?

By: wire (wire) 2004-03-22 10:02:28.000-0600

This patch was applied in chan_sip.c rev 1.252

By: Olle Johansson (oej) 2004-03-22 10:58:53.000-0600

Patch applied to CVS.