Allow for reloading SRTP crypto keys within the same SIP dialog
authorMatthew Jordan <mjordan@digium.com>
Fri, 27 Apr 2012 14:45:08 +0000 (14:45 +0000)
committerMatthew Jordan <mjordan@digium.com>
Fri, 27 Apr 2012 14:45:08 +0000 (14:45 +0000)
As a continuation of the patch in r356604, which allowed for the
reloading of SRTP keys in re-INVITE transfer scenarios, this patch
addresses the more common case where a new key is requested within
the context of a current SIP dialog.  This can occur, for example, when
certain phones request a SIP hold.

Previously, once a dialog was associated with an SRTP object, any
subsequent attempt to process crypto keys in any SDP offer - either
the current one or a new offer in a new SIP request - were ignored.  This
patch changes this behavior to only ignore subsequent crypto keys within
the current SDP offer, but allows future SDP offers to change the keys.

(issue ASTERISK-19253)
Reported by: Thomas Arimont
Tested by: Thomas Arimont

Review: https://reviewboard.asteriskorg/r/1885/
........

Merged revisions 364203 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........

Merged revisions 364204 from http://svn.asterisk.org/svn/asterisk/branches/10

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

channels/chan_sip.c

index 0d5930d..45ae893 100644 (file)
@@ -9165,6 +9165,7 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
                int video = FALSE;
                int image = FALSE;
                int text = FALSE;
+               int processed_crypto = FALSE;
                char protocol[5] = {0,};
                int x;
 
@@ -9346,28 +9347,34 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
                        case 'a':
                                /* Audio specific scanning */
                                if (audio) {
-                                       if (process_sdp_a_sendonly(value, &sendonly))
+                                       if (process_sdp_a_sendonly(value, &sendonly)) {
                                                processed = TRUE;
-                                       else if (process_crypto(p, p->rtp, &p->srtp, value))
+                                       } else if (!processed_crypto && process_crypto(p, p->rtp, &p->srtp, value)) {
+                                               processed_crypto = TRUE;
                                                processed = TRUE;
-                                       else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec))
+                                       } else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec)) {
                                                processed = TRUE;
+                                       }
                                }
                                /* Video specific scanning */
                                else if (video) {
-                                       if (process_sdp_a_sendonly(value, &vsendonly))
+                                       if (process_sdp_a_sendonly(value, &vsendonly)) {
                                                processed = TRUE;
-                                       else if (process_crypto(p, p->vrtp, &p->vsrtp, value))
+                                       } else if (!processed_crypto && process_crypto(p, p->vrtp, &p->vsrtp, value)) {
+                                               processed_crypto = TRUE;
                                                processed = TRUE;
-                                       else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec))
+                                       } else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec)) {
                                                processed = TRUE;
+                                       }
                                }
                                /* Text (T.140) specific scanning */
                                else if (text) {
-                                       if (process_sdp_a_text(value, p, &newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec))
+                                       if (process_sdp_a_text(value, p, &newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec)) {
                                                processed = TRUE;
-                                       else if (process_crypto(p, p->trtp, &p->tsrtp, value))
+                                       } else if (!processed_crypto && process_crypto(p, p->trtp, &p->tsrtp, value)) {
+                                               processed_crypto = TRUE;
                                                processed = TRUE;
+                                       }
                                }
                                /* Image (T.38 FAX) specific scanning */
                                else if (image) {
@@ -30805,12 +30812,6 @@ static int process_crypto(struct sip_pvt *p, struct ast_rtp_instance *rtp, struc
                }
        }
 
-       /* For now, when we receive an INVITE just take the first successful crypto line */
-       if ((*srtp)->crypto && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
-               ast_debug(3, "We've already processed a crypto attribute, skipping '%s'\n", a);
-               return FALSE;
-       }
-
        if (!(*srtp)->crypto && !((*srtp)->crypto = sdp_crypto_setup())) {
                return FALSE;
        }