media/mtransport/third_party/nICEr/src/ice/ice_parser.c

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /*
     2 Copyright (c) 2007, Adobe Systems, Incorporated
     3 All rights reserved.
     5 Redistribution and use in source and binary forms, with or without
     6 modification, are permitted provided that the following conditions are
     7 met:
     9 * Redistributions of source code must retain the above copyright
    10   notice, this list of conditions and the following disclaimer.
    12 * Redistributions in binary form must reproduce the above copyright
    13   notice, this list of conditions and the following disclaimer in the
    14   documentation and/or other materials provided with the distribution.
    16 * Neither the name of Adobe Systems, Network Resonance nor the names of its
    17   contributors may be used to endorse or promote products derived from
    18   this software without specific prior written permission.
    20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    21 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    24 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    25 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    26 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    27 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    28 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    29 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    31 */
    35 static char *RCSSTRING __UNUSED__="$Id: ice_parser.c,v 1.2 2008/04/28 17:59:01 ekr Exp $";
    37 #include <csi_platform.h>
    38 #include <sys/types.h>
    39 #ifdef WIN32
    40 #include <winsock2.h>
    41 #else
    42 #include <sys/socket.h>
    43 #include <netinet/in.h>
    44 #include <arpa/inet.h>
    45 #include <strings.h>
    46 #endif
    47 #include <string.h>
    48 #include <assert.h>
    49 #include <ctype.h>
    50 #include "nr_api.h"
    51 #include "ice_ctx.h"
    52 #include "ice_candidate.h"
    53 #include "ice_reg.h"
    55 static void
    56 skip_whitespace(char **str)
    57 {
    58     char *c = *str;
    59     while (*c == ' ')
    60         ++c;
    62     *str = c;
    63 }
    65 static void
    66 fast_forward(char **str, int skip)
    67 {
    68     char *c = *str;
    69     while (*c != '\0' && skip-- > 0)
    70         ++c;
    72     *str = c;
    73 }
    75 static void
    76 skip_to_past_space(char **str)
    77 {
    78     char *c = *str;
    79     while (*c != ' ' && *c != '\0')
    80         ++c;
    82     *str = c;
    84     skip_whitespace(str);
    85 }
    87 static int
    88 grab_token(char **str, char **out)
    89 {
    90     int _status;
    91     char *c = *str;
    92     int len;
    93     char *tmp;
    95     while (*c != ' ' && *c != '\0')
    96         ++c;
    98     len = c - *str;
   100     tmp = RMALLOC(len + 1);
   101     if (!tmp)
   102         ABORT(R_NO_MEMORY);
   104     memcpy(tmp, *str, len);
   105     tmp[len] = '\0';
   107     *str = c;
   108     *out = tmp;
   110     _status = 0;
   111 abort:
   112     return _status;
   113 }
   115 int
   116 nr_ice_peer_candidate_from_attribute(nr_ice_ctx *ctx,char *orig,nr_ice_media_stream *stream,nr_ice_candidate **candp)
   117 {
   118     int r,_status;
   119     char* str = orig;
   120     nr_ice_candidate *cand;
   121     char *connection_address=0;
   122     unsigned int port;
   123     in_addr_t addr;
   124     int i;
   125     unsigned int component_id;
   126     char *rel_addr=0;
   128     if(!(cand=RCALLOC(sizeof(nr_ice_candidate))))
   129         ABORT(R_NO_MEMORY);
   131     if(!(cand->label=r_strdup(orig)))
   132         ABORT(R_NO_MEMORY);
   134     cand->ctx=ctx;
   135     cand->isock=0;
   136     cand->state=NR_ICE_CAND_PEER_CANDIDATE_UNPAIRED;
   137     cand->stream=stream;
   138     skip_whitespace(&str);
   140     /* Candidate attr */
   141     if (strncasecmp(str, "candidate:", 10))
   142         ABORT(R_BAD_DATA);
   144     fast_forward(&str, 10);
   145     if (*str == '\0')
   146         ABORT(R_BAD_DATA);
   148     skip_whitespace(&str);
   149     if (*str == '\0')
   150         ABORT(R_BAD_DATA);
   152     /* Foundation */
   153     if ((r=grab_token(&str, &cand->foundation)))
   154         ABORT(r);
   156     if (*str == '\0')
   157         ABORT(R_BAD_DATA);
   159     skip_whitespace(&str);
   160     if (*str == '\0')
   161         ABORT(R_BAD_DATA);
   163     /* component */
   164     if (sscanf(str, "%u", &component_id) != 1)
   165         ABORT(R_BAD_DATA);
   167     if (component_id < 1 || component_id > 256)
   168         ABORT(R_BAD_DATA);
   170     cand->component_id = (UCHAR)component_id;
   172     skip_to_past_space(&str);
   173     if (*str == '\0')
   174         ABORT(R_BAD_DATA);
   176     /* Protocol */
   177     if (strncasecmp(str, "UDP", 3))
   178         ABORT(R_BAD_DATA);
   180     fast_forward(&str, 3);
   181     if (*str == '\0')
   182         ABORT(R_BAD_DATA);
   184     skip_whitespace(&str);
   185     if (*str == '\0')
   186         ABORT(R_BAD_DATA);
   188     /* priority */
   189     if (sscanf(str, "%u", &cand->priority) != 1)
   190         ABORT(R_BAD_DATA);
   192     if (cand->priority < 1)
   193         ABORT(R_BAD_DATA);
   195     skip_to_past_space(&str);
   196     if (*str == '\0')
   197         ABORT(R_BAD_DATA);
   199     /* Peer address/port */
   200     if ((r=grab_token(&str, &connection_address)))
   201         ABORT(r);
   203     if (*str == '\0')
   204         ABORT(R_BAD_DATA);
   206     addr = inet_addr(connection_address);
   207     if (addr == INADDR_NONE)
   208         ABORT(R_BAD_DATA);
   210     skip_whitespace(&str);
   211     if (*str == '\0')
   212         ABORT(R_BAD_DATA);
   214     if (sscanf(str, "%u", &port) != 1)
   215         ABORT(R_BAD_DATA);
   217     if (port < 1 || port > 0x0FFFF)
   218         ABORT(R_BAD_DATA);
   220     /* Assume v4 for now */
   221     if(r=nr_ip4_port_to_transport_addr(ntohl(addr),port,IPPROTO_UDP,&cand->addr))
   222       ABORT(r);
   224     skip_to_past_space(&str);
   225     if (*str == '\0')
   226         ABORT(R_BAD_DATA);
   228     /* Type */
   229     if (strncasecmp("typ", str, 3))
   230         ABORT(R_BAD_DATA);
   232     fast_forward(&str, 3);
   233     if (*str == '\0')
   234         ABORT(R_BAD_DATA);
   236     skip_whitespace(&str);
   237     if (*str == '\0')
   238         ABORT(R_BAD_DATA);
   240     assert(nr_ice_candidate_type_names[0] == 0);
   241 #if __STDC_VERSION__ >= 201112L
   242     _Static_assert(nr_ice_candidate_type_names[0] == 0,"Candidate name array is misformatted");
   243 #endif
   245     for (i = 1; nr_ice_candidate_type_names[i]; ++i) {
   246         if(!strncasecmp(nr_ice_candidate_type_names[i], str, strlen(nr_ice_candidate_type_names[i]))) {
   247             cand->type=i;
   248             break;
   249         }
   250     }
   251     if (nr_ice_candidate_type_names[i] == 0)
   252         ABORT(R_BAD_DATA);
   254     fast_forward(&str, strlen(nr_ice_candidate_type_names[i]));
   256     /* Look for the other side's raddr, rport */
   257     /* raddr, rport */
   258     switch (cand->type) {
   259     case HOST:
   260         break;
   261     case SERVER_REFLEXIVE:
   262     case PEER_REFLEXIVE:
   263     case RELAYED:
   265         skip_whitespace(&str);
   266         if (*str == '\0')
   267             ABORT(R_BAD_DATA);
   269         if (strncasecmp("raddr", str, 5))
   270             ABORT(R_BAD_DATA);
   272         fast_forward(&str, 5);
   273         if (*str == '\0')
   274             ABORT(R_BAD_DATA);
   276         skip_whitespace(&str);
   277         if (*str == '\0')
   278             ABORT(R_BAD_DATA);
   280         if ((r=grab_token(&str, &rel_addr)))
   281             ABORT(r);
   283         if (*str == '\0')
   284             ABORT(R_BAD_DATA);
   286         addr = inet_addr(rel_addr);
   287         if (addr == INADDR_NONE)
   288             ABORT(R_BAD_DATA);
   290         skip_whitespace(&str);
   291         if (*str == '\0')
   292             ABORT(R_BAD_DATA);
   294         if (strncasecmp("rport", str, 5))
   295               ABORT(R_BAD_DATA);
   297         fast_forward(&str, 5);
   298         if (*str == '\0')
   299             ABORT(R_BAD_DATA);
   301         skip_whitespace(&str);
   302         if (*str == '\0')
   303             ABORT(R_BAD_DATA);
   305         if (sscanf(str, "%u", &port) != 1)
   306             ABORT(R_BAD_DATA);
   308         if (port < 1 || port > 0x0FFFF)
   309             ABORT(R_BAD_DATA);
   311         /* Assume v4 for now */
   312         if(r=nr_ip4_port_to_transport_addr(ntohl(addr),port,IPPROTO_UDP,&cand->base))
   313           ABORT(r);
   315         skip_to_past_space(&str);
   316         /* it's expected to be at EOD at this point */
   318         break;
   319     default:
   320         ABORT(R_INTERNAL);
   321         break;
   322     }
   324     skip_whitespace(&str);
   326     /* Ignore extensions per RFC 5245 S 15.1 */
   327 #if 0
   328     /* This used to be an assert, but we don't want to exit on invalid
   329        remote data */
   330     if (strlen(str) != 0) {
   331       ABORT(R_BAD_DATA);
   332     }
   333 #endif
   335     nr_ice_candidate_compute_codeword(cand);
   337     *candp=cand;
   339     _status=0;
   340   abort:
   341     if (_status){
   342         r_log(LOG_ICE,LOG_WARNING,"ICE(%s): Error parsing attribute: %s",ctx->label,orig);
   343         nr_ice_candidate_destroy(&cand);
   344     }
   346     RFREE(connection_address);
   347     RFREE(rel_addr);
   348     return(_status);
   349 }
   352 int
   353 nr_ice_peer_ctx_parse_media_stream_attribute(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, char *attr)
   354 {
   355     int r,_status;
   356     char *orig = 0;
   357     char *str;
   359     orig = str = attr;
   361     if (!strncasecmp(str, "ice-ufrag:", 10)) {
   362       fast_forward(&str, 10);
   363       if (*str == '\0')
   364         ABORT(R_BAD_DATA);
   366       skip_whitespace(&str);
   367       if (*str == '\0')
   368         ABORT(R_BAD_DATA);
   370       if ((r=grab_token(&str, &stream->ufrag)))
   371         ABORT(r);
   372     }
   373     else if (!strncasecmp(str, "ice-pwd:", 8)) {
   374       fast_forward(&str, 8);
   375       if (*str == '\0')
   376         ABORT(R_BAD_DATA);
   378       skip_whitespace(&str);
   379       if (*str == '\0')
   380         ABORT(R_BAD_DATA);
   382       if ((r=grab_token(&str, &stream->pwd)))
   383         ABORT(r);
   384     }
   385     else {
   386       ABORT(R_BAD_DATA);
   387     }
   389     skip_whitespace(&str);
   391     /* RFC 5245 grammar doesn't have an extension point for ice-pwd or
   392        ice-ufrag: if there's anything left on the line, we treat it as bad. */
   393     if (str[0] != '\0') {
   394       ABORT(R_BAD_DATA);
   395     }
   397     _status=0;
   398   abort:
   399     if (_status) {
   400       if (orig)
   401         r_log(LOG_ICE,LOG_WARNING,"ICE-PEER(%s): Error parsing attribute: %s",pctx->label,orig);
   402     }
   404     return(_status);
   405 }
   407 int
   408 nr_ice_peer_ctx_parse_global_attributes(nr_ice_peer_ctx *pctx, char **attrs, int attr_ct)
   409 {
   410     int r,_status;
   411     int i;
   412     char *orig = 0;
   413     char *str;
   414     char *component_id = 0;
   415     char *connection_address = 0;
   416     unsigned int port;
   417     in_addr_t addr;
   418     char *ice_option_tag = 0;
   420     for(i=0;i<attr_ct;i++){
   421         orig = str = attrs[i];
   423         component_id = 0;
   424         connection_address = 0;
   425         ice_option_tag = 0;
   427         if (!strncasecmp(str, "remote-candidates:", 18)) {
   428             fast_forward(&str, 18);
   429             skip_whitespace(&str);
   431             while (*str != '\0') {
   432                 if ((r=grab_token(&str, &component_id)))
   433                     ABORT(r);
   435                 if (*str == '\0')
   436                     ABORT(R_BAD_DATA);
   438                 skip_whitespace(&str);
   439                 if (*str == '\0')
   440                     ABORT(R_BAD_DATA);
   442                 if ((r=grab_token(&str, &connection_address)))
   443                     ABORT(r);
   445                 if (*str == '\0')
   446                     ABORT(R_BAD_DATA);
   448                 addr = inet_addr(connection_address);
   449                 if (addr == INADDR_NONE)
   450                     ABORT(R_BAD_DATA);
   452                 skip_whitespace(&str);
   453                 if (*str == '\0')
   454                     ABORT(R_BAD_DATA);
   456                 if (sscanf(str, "%u", &port) != 1)
   457                     ABORT(R_BAD_DATA);
   459                 if (port < 1 || port > 0x0FFFF)
   460                     ABORT(R_BAD_DATA);
   462                 skip_to_past_space(&str);
   464 #if 0
   465                 /* TODO: !nn! just drop on the floor for now, later put somewhere */
   466                 /* Assume v4 for now */
   467                 if(r=nr_ip4_port_to_transport_addr(ntohl(addr),port,IPPROTO_UDP,&candidate->base))
   468                   ABORT(r);
   470                 TAILQ_INSERT_TAIL(head, elm, field);
   471 #endif
   473                 component_id = 0;  /* prevent free */
   474                 RFREE(connection_address);
   475                 connection_address = 0;  /* prevent free */
   476             }
   477         }
   478         else if (!strncasecmp(str, "ice-lite", 8)) {
   479             pctx->peer_lite = 1;
   481             fast_forward(&str, 8);
   482         }
   483         else if (!strncasecmp(str, "ice-mismatch", 12)) {
   484             pctx->peer_ice_mismatch = 1;
   486             fast_forward(&str, 12);
   487         }
   488         else if (!strncasecmp(str, "ice-ufrag:", 10)) {
   489             fast_forward(&str, 10);
   490             if (*str == '\0')
   491                 ABORT(R_BAD_DATA);
   493             skip_whitespace(&str);
   494             if (*str == '\0')
   495                 ABORT(R_BAD_DATA);
   497             RFREE(pctx->peer_ufrag);
   498             pctx->peer_ufrag = 0;
   499             if ((r=grab_token(&str, &pctx->peer_ufrag)))
   500                 ABORT(r);
   501         }
   502         else if (!strncasecmp(str, "ice-pwd:", 8)) {
   503             fast_forward(&str, 8);
   504             if (*str == '\0')
   505                 ABORT(R_BAD_DATA);
   507             skip_whitespace(&str);
   508             if (*str == '\0')
   509                 ABORT(R_BAD_DATA);
   511             RFREE(pctx->peer_pwd);
   512             pctx->peer_pwd = 0;
   513             if ((r=grab_token(&str, &pctx->peer_pwd)))
   514                 ABORT(r);
   515         }
   516         else if (!strncasecmp(str, "ice-options:", 12)) {
   517             fast_forward(&str, 12);
   518             skip_whitespace(&str);
   520             while (*str != '\0') {
   521                 if ((r=grab_token(&str, &ice_option_tag)))
   522                     ABORT(r);
   524                 skip_whitespace(&str);
   526                 //TODO: for now, just throw away; later put somewhere
   527                 RFREE(ice_option_tag);
   529                 ice_option_tag = 0;  /* prevent free */
   530             }
   531         }
   532         else {
   533             ABORT(R_BAD_DATA);
   534         }
   536         skip_whitespace(&str);
   538       /* RFC 5245 grammar doesn't have an extension point for any of the
   539          preceding attributes: if there's anything left on the line, we
   540          treat it as bad data. */
   541       if (str[0] != '\0') {
   542         ABORT(R_BAD_DATA);
   543       }
   544     }
   546     _status=0;
   547   abort:
   548     if (_status) {
   549       if (orig)
   550         r_log(LOG_ICE,LOG_WARNING,"ICE-PEER(%s): Error parsing attribute: %s",pctx->label,orig);
   551     }
   553     RFREE(connection_address);
   554     RFREE(component_id);
   555     RFREE(ice_option_tag);
   556     return(_status);
   557 }

mercurial