media/mtransport/third_party/nrappkit/src/registry/registry.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  *
     3  *    registry.c
     4  *
     5  *    $Source: /Users/ekr/tmp/nrappkit-dump/nrappkit/src/registry/registry.c,v $
     6  *    $Revision: 1.6 $
     7  *    $Date: 2007/11/21 00:09:12 $
     8  *
     9  *    Datastore for tracking configuration and related info.
    10  *
    11  *
    12  *    Copyright (C) 2005, Network Resonance, Inc.
    13  *    Copyright (C) 2006, Network Resonance, Inc.
    14  *    All Rights Reserved
    15  *
    16  *    Redistribution and use in source and binary forms, with or without
    17  *    modification, are permitted provided that the following conditions
    18  *    are met:
    19  *
    20  *    1. Redistributions of source code must retain the above copyright
    21  *       notice, this list of conditions and the following disclaimer.
    22  *    2. Redistributions in binary form must reproduce the above copyright
    23  *       notice, this list of conditions and the following disclaimer in the
    24  *       documentation and/or other materials provided with the distribution.
    25  *    3. Neither the name of Network Resonance, Inc. nor the name of any
    26  *       contributors to this software may be used to endorse or promote
    27  *       products derived from this software without specific prior written
    28  *       permission.
    29  *
    30  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
    31  *    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    32  *    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    33  *    ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
    34  *    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    35  *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    36  *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    37  *    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    38  *    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    39  *    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    40  *    POSSIBILITY OF SUCH DAMAGE.
    41  *
    42  *
    43  */
    45 #include <assert.h>
    46 #include <string.h>
    47 #ifndef _MSC_VER
    48 #include <strings.h>
    49 #include <sys/param.h>
    50 #include <netinet/in.h>
    51 #endif
    52 #ifdef OPENSSL
    53 #include <openssl/ssl.h>
    54 #endif
    55 #include <ctype.h>
    56 #include "registry.h"
    57 #include "registry_int.h"
    58 #include "registry_vtbl.h"
    59 #include "r_assoc.h"
    60 #include "nr_common.h"
    61 #include "r_log.h"
    62 #include "r_errors.h"
    63 #include "r_macros.h"
    64 #include "c2ru.h"
    66 /* vtbl used to switch hit between local and remote invocations */
    67 static nr_registry_module *reg_vtbl = 0;
    69 /* must be in the order the types are numbered */
    70 static char *typenames[] = { "char", "UCHAR", "INT2", "UINT2", "INT4", "UINT4", "INT8", "UINT8", "double", "Data", "string", "registry" };
    72 int NR_LOG_REGISTRY=0;
    74 NR_registry NR_TOP_LEVEL_REGISTRY = "";
    76 int
    77 NR_reg_init(void *mode)
    78 {
    79     int r, _status;
    80     nr_registry_module *module = (nr_registry_module*)mode;
    81 #ifdef SANITY_CHECKS
    82     NR_registry registry;
    83 #endif
    85     if (reg_vtbl) {
    86         if (reg_vtbl != module) {
    87           r_log(LOG_GENERIC,LOG_ERR,"Can't reinitialize registry in different mode");
    88           ABORT(R_INTERNAL);
    89         }
    91         return(0);
    92     }
    94     reg_vtbl = module;
    96     if ((r=reg_vtbl->vtbl->init(mode)))
    97         ABORT(r);
    99 #ifdef SANITY_CHECKS
   100     if ((r=NR_reg_get_registry(NR_TOP_LEVEL_REGISTRY, registry)))
   101         ABORT(r);
   102     assert(strcmp(registry, NR_TOP_LEVEL_REGISTRY) == 0);
   103 #endif
   105      r_log_init();
   106      r_log_register("registry",&NR_LOG_REGISTRY);
   108     _status=0;
   109   abort:
   110     r_log(NR_LOG_REGISTRY,
   111           (_status ? LOG_ERR                        :  LOG_INFO),
   112           (_status ? "Couldn't initialize registry" : "Initialized registry"));
   113     return(_status);
   114 }
   116 int
   117 NR_reg_initted(void)
   118 {
   119     return reg_vtbl!=0;
   120 }
   122 #define NRREGGET(func, method, type)                                \
   123 int                                                                 \
   124 func(NR_registry name, type *out)                                   \
   125 {                                                                   \
   126     return reg_vtbl->vtbl->method(name, out);                             \
   127 }
   129 NRREGGET(NR_reg_get_char,     get_char,     char)
   130 NRREGGET(NR_reg_get_uchar,    get_uchar,    UCHAR)
   131 NRREGGET(NR_reg_get_int2,     get_int2,     INT2)
   132 NRREGGET(NR_reg_get_uint2,    get_uint2,    UINT2)
   133 NRREGGET(NR_reg_get_int4,     get_int4,     INT4)
   134 NRREGGET(NR_reg_get_uint4,    get_uint4,    UINT4)
   135 NRREGGET(NR_reg_get_int8,     get_int8,     INT8)
   136 NRREGGET(NR_reg_get_uint8,    get_uint8,    UINT8)
   137 NRREGGET(NR_reg_get_double,   get_double,   double)
   139 int
   140 NR_reg_get_registry(NR_registry name, NR_registry out)
   141 {
   142     return reg_vtbl->vtbl->get_registry(name, out);
   143 }
   145 int
   146 NR_reg_get_bytes(NR_registry name, UCHAR *out, size_t size, size_t *length)
   147 {
   148     return reg_vtbl->vtbl->get_bytes(name, out, size, length);
   149 }
   151 int
   152 NR_reg_get_string(NR_registry name, char *out, size_t size)
   153 {
   154     return reg_vtbl->vtbl->get_string(name, out, size);
   155 }
   157 int
   158 NR_reg_get_length(NR_registry name, size_t *length)
   159 {
   160     return reg_vtbl->vtbl->get_length(name, length);
   161 }
   163 int
   164 NR_reg_get_type(NR_registry name, NR_registry_type type)
   165 {
   166     return reg_vtbl->vtbl->get_type(name, type);
   167 }
   169 #define NRREGSET(func, method, type)                            \
   170 int                                                             \
   171 func(NR_registry name, type data)                               \
   172 {                                                               \
   173     return reg_vtbl->vtbl->method(name, data);                        \
   174 }
   176 NRREGSET(NR_reg_set_char,     set_char,     char)
   177 NRREGSET(NR_reg_set_uchar,    set_uchar,    UCHAR)
   178 NRREGSET(NR_reg_set_int2,     set_int2,     INT2)
   179 NRREGSET(NR_reg_set_uint2,    set_uint2,    UINT2)
   180 NRREGSET(NR_reg_set_int4,     set_int4,     INT4)
   181 NRREGSET(NR_reg_set_uint4,    set_uint4,    UINT4)
   182 NRREGSET(NR_reg_set_int8,     set_int8,     INT8)
   183 NRREGSET(NR_reg_set_uint8,    set_uint8,    UINT8)
   184 NRREGSET(NR_reg_set_double,   set_double,   double)
   185 NRREGSET(NR_reg_set_string,   set_string,   char*)
   187 int
   188 NR_reg_set_registry(NR_registry name)
   189 {
   190     return reg_vtbl->vtbl->set_registry(name);
   191 }
   193 int
   194 NR_reg_set_bytes(NR_registry name, unsigned char *data, size_t length)
   195 {
   196     return reg_vtbl->vtbl->set_bytes(name, data, length);
   197 }
   200 int
   201 NR_reg_del(NR_registry name)
   202 {
   203     return reg_vtbl->vtbl->del(name);
   204 }
   206 int
   207 NR_reg_fin(NR_registry name)
   208 {
   209     return reg_vtbl->vtbl->fin(name);
   210 }
   212 int
   213 NR_reg_get_child_count(char *parent, unsigned int *count)
   214 {
   215     assert(sizeof(count) == sizeof(size_t));
   216     return reg_vtbl->vtbl->get_child_count(parent, (size_t*)count);
   217 }
   219 int
   220 NR_reg_get_child_registry(char *parent, unsigned int i, NR_registry child)
   221 {
   222     int r, _status;
   223     size_t count;
   224     NR_registry *children=0;
   226     if ((r=reg_vtbl->vtbl->get_child_count(parent, &count)))
   227       ABORT(r);
   229     if (i >= count)
   230         ABORT(R_NOT_FOUND);
   231     else {
   232         count++;
   233         children = (NR_registry *)RCALLOC(count * sizeof(NR_registry));
   234         if (!children)
   235             ABORT(R_NO_MEMORY);
   237         if ((r=reg_vtbl->vtbl->get_children(parent, children, count, &count)))
   238             ABORT(r);
   240         if (i >= count)
   241             ABORT(R_NOT_FOUND);
   243         strncpy(child, children[i], sizeof(NR_registry));
   244     }
   246     _status=0;
   247   abort:
   248     RFREE(children);
   249     return(_status);
   250 }
   252 int
   253 NR_reg_get_children(NR_registry parent, NR_registry *children, size_t size, size_t *length)
   254 {
   255     return reg_vtbl->vtbl->get_children(parent, children, size, length);
   256 }
   258 int
   259 NR_reg_dump()
   260 {
   261     int r, _status;
   263     if ((r=reg_vtbl->vtbl->dump(0)))
   264       ABORT(r);
   266     _status=0;
   267   abort:
   268     return(_status);
   269 }
   271 // convenience methods, call RFREE on the returned data
   272 int
   273 NR_reg_alloc_data(NR_registry name, Data *data)
   274 {
   275     int r, _status;
   276     size_t length;
   277     UCHAR  *tmp = 0;
   278     size_t sanity_check;
   280     if ((r=NR_reg_get_length(name, &length)))
   281       ABORT(r);
   283     if (!(tmp = (void*)RMALLOC(length)))
   284       ABORT(R_NO_MEMORY);
   286     if ((r=NR_reg_get_bytes(name, tmp, length, &sanity_check)))
   287       ABORT(r);
   289     assert(length == sanity_check);
   291     data->len = length;
   292     data->data = tmp;
   294     _status=0;
   295   abort:
   296     if (_status) {
   297       if (tmp) RFREE(tmp);
   298     }
   299     return(_status);
   300 }
   302 int
   303 NR_reg_alloc_string(NR_registry name, char **data)
   304 {
   305     int r, _status;
   306     size_t length;
   307     char  *tmp = 0;
   309     if ((r=NR_reg_get_length(name, &length)))
   310       ABORT(r);
   312     if (!(tmp = (void*)RMALLOC(length+1)))
   313       ABORT(R_NO_MEMORY);
   315     if ((r=NR_reg_get_string(name, tmp, length+1)))
   316       ABORT(r);
   318     assert(length == strlen(tmp));
   320     *data = tmp;
   322     _status=0;
   323   abort:
   324     if (_status) {
   325       if (tmp) RFREE(tmp);
   326     }
   327     return(_status);
   328 }
   331 char *
   332 nr_reg_type_name(int type)
   333 {
   334     if ((type < NR_REG_TYPE_CHAR) || (type > NR_REG_TYPE_REGISTRY))
   335        return(NULL);
   337     return(typenames[type]);
   338 }
   340 int
   341 nr_reg_compute_type(char *typename, int *type)
   342 {
   343     int _status;
   344     int i;
   346 #ifdef SANITY_CHECKS
   347     assert(!strcasecmp(typenames[NR_REG_TYPE_CHAR],     "char"));
   348     assert(!strcasecmp(typenames[NR_REG_TYPE_UCHAR],    "UCHAR"));
   349     assert(!strcasecmp(typenames[NR_REG_TYPE_INT2],     "INT2"));
   350     assert(!strcasecmp(typenames[NR_REG_TYPE_UINT2],    "UINT2"));
   351     assert(!strcasecmp(typenames[NR_REG_TYPE_INT4],     "INT4"));
   352     assert(!strcasecmp(typenames[NR_REG_TYPE_UINT4],    "UINT4"));
   353     assert(!strcasecmp(typenames[NR_REG_TYPE_INT8],     "INT8"));
   354     assert(!strcasecmp(typenames[NR_REG_TYPE_UINT8],    "UINT8"));
   355     assert(!strcasecmp(typenames[NR_REG_TYPE_DOUBLE],   "double"));
   356     assert(!strcasecmp(typenames[NR_REG_TYPE_BYTES],    "Data"));
   357     assert(!strcasecmp(typenames[NR_REG_TYPE_STRING],   "string"));
   358     assert(!strcasecmp(typenames[NR_REG_TYPE_REGISTRY], "registry"));
   359     assert(sizeof(typenames)/sizeof(*typenames) == (NR_REG_TYPE_REGISTRY+1));
   360 #endif
   362     for (i = 0; i < sizeof(typenames)/sizeof(*typenames); ++i) {
   363       if (!strcasecmp(typenames[i], typename)) {
   364         *type = i;
   365         return 0;
   366       }
   367     }
   368     ABORT(R_BAD_ARGS);
   370     _status=0;
   371   abort:
   372     return(_status);
   373 }
   375 /* More convenience functions: the same as their parents but they
   376    take a prefix and a suffix */
   377 #define NRGET2(func, type, get) \
   378 int                                                                  \
   379 func(NR_registry parent, char *child, type *out)                     \
   380 {                                                                    \
   381   int r, _status;                                                    \
   382   NR_registry registry;                                              \
   383                                                                      \
   384   if ((r = NR_reg_make_registry(parent, child, registry)))           \
   385     ABORT(r);                                                        \
   386                                                                      \
   387   if ((r = get(registry, out))) {                                    \
   388     ABORT(r);                                                        \
   389   }                                                                  \
   390                                                                      \
   391   _status = 0;                                                       \
   392 abort:                                                               \
   393   return (_status);                                                  \
   394 }
   396 NRGET2(NR_reg_get2_char,     char,    NR_reg_get_char)
   397 NRGET2(NR_reg_get2_uchar,    UCHAR,   NR_reg_get_uchar)
   398 NRGET2(NR_reg_get2_int2,     INT2,    NR_reg_get_int2)
   399 NRGET2(NR_reg_get2_uint2,    UINT2,   NR_reg_get_uint2)
   400 NRGET2(NR_reg_get2_int4,     INT4,    NR_reg_get_int4)
   401 NRGET2(NR_reg_get2_uint4,    UINT4,   NR_reg_get_uint4)
   402 NRGET2(NR_reg_get2_int8,     INT8,    NR_reg_get_int8)
   403 NRGET2(NR_reg_get2_uint8,    UINT8,   NR_reg_get_uint8)
   404 NRGET2(NR_reg_get2_double,   double,  NR_reg_get_double)
   405 NRGET2(NR_reg_alloc2_string,   char*,   NR_reg_alloc_string)
   406 NRGET2(NR_reg_alloc2_data,     Data,    NR_reg_alloc_data)
   408 int
   409 NR_reg_get2_bytes(NR_registry parent, char *child, UCHAR *out, size_t size, size_t *length)
   410 {
   411     int r, _status;
   412     NR_registry registry;
   414     if ((r=NR_reg_make_registry(parent, child, registry)))
   415       ABORT(r);
   417     if ((r=NR_reg_get_bytes(registry, out, size, length)))
   418       ABORT(r);
   420     _status = 0;
   421 abort:
   422     return (_status);
   423 }
   425 int
   426 NR_reg_get2_string(NR_registry parent, char *child, char *out, size_t size)
   427 {
   428     int r, _status;
   429     NR_registry registry;
   431     if ((r=NR_reg_make_registry(parent, child, registry)))
   432       ABORT(r);
   434     if ((r=NR_reg_get_string(registry, out, size)))
   435       ABORT(r);
   437     _status = 0;
   438 abort:
   439     return (_status);
   440 }
   442 /* More convenience functions: the same as their parents but they
   443    take a prefix and a suffix */
   444 #define NRSET2(func, type, set) \
   445 int                                                                  \
   446 func(NR_registry parent, char *child, type in)                       \
   447 {                                                                    \
   448   int r, _status;                                                    \
   449   NR_registry registry;                                              \
   450                                                                      \
   451   if ((r = NR_reg_make_registry(parent, child, registry)))           \
   452     ABORT(r);                                                        \
   453                                                                      \
   454   if ((r = set(registry, in))) {                                     \
   455     ABORT(r);                                                        \
   456   }                                                                  \
   457                                                                      \
   458   _status = 0;                                                       \
   459 abort:                                                               \
   460   return (_status);                                                  \
   461 }
   463 NRSET2(NR_reg_set2_char,     char,    NR_reg_set_char)
   464 NRSET2(NR_reg_set2_uchar,    UCHAR,   NR_reg_set_uchar)
   465 NRSET2(NR_reg_set2_int2,     INT2,    NR_reg_set_int2)
   466 NRSET2(NR_reg_set2_uint2,    UINT2,   NR_reg_set_uint2)
   467 NRSET2(NR_reg_set2_int4,     INT4,    NR_reg_set_int4)
   468 NRSET2(NR_reg_set2_uint4,    UINT4,   NR_reg_set_uint4)
   469 NRSET2(NR_reg_set2_int8,     INT8,    NR_reg_set_int8)
   470 NRSET2(NR_reg_set2_uint8,    UINT8,   NR_reg_set_uint8)
   471 NRSET2(NR_reg_set2_double,   double,  NR_reg_set_double)
   472 NRSET2(NR_reg_set2_string,   char*,   NR_reg_set_string)
   474 int
   475 NR_reg_set2_bytes(NR_registry prefix, char *name, UCHAR *data, size_t length)
   476 {
   477     int r, _status;
   478     NR_registry registry;
   480     if ((r = NR_reg_make_registry(prefix, name, registry)))
   481       ABORT(r);
   483     if ((r = NR_reg_set_bytes(registry, data, length)))
   484       ABORT(r);
   486     _status = 0;
   487 abort:
   488     return (_status);
   489 }
   492 int
   493 NR_reg_make_child_registry(NR_registry parent, NR_registry descendant, unsigned int generation, NR_registry child)
   494 {
   495     int _status;
   496     size_t length;
   498     length = strlen(parent);
   500     if (strncasecmp(parent, descendant, length))
   501         ABORT(R_BAD_ARGS);
   503     while (descendant[length] != '\0') {
   504         if (descendant[length] == '.') {
   505             if (generation == 0)
   506                 break;
   508             --generation;
   509         }
   511         ++length;
   512         if (length >= sizeof(NR_registry))
   513             ABORT(R_BAD_ARGS);
   514     }
   516     strncpy(child, descendant, length);
   517     child[length] = '\0';
   519     _status=0;
   520   abort:
   521     return(_status);
   522 }
   524 int
   525 NR_reg_get2_child_count(NR_registry base, NR_registry name, unsigned int *count)
   526   {
   527     int r, _status;
   528     NR_registry registry;
   530     if ((r=nr_c2ru_make_registry(base, name, registry)))
   531       ABORT(r);
   533     if (r=NR_reg_get_child_count(registry,count))
   534       ABORT(r);
   536     _status=0;
   537   abort:
   538     return(_status);
   539   }
   541 int
   542 NR_reg_get2_child_registry(NR_registry base, NR_registry name, unsigned int i, NR_registry child)
   543   {
   544     int r, _status;
   545     NR_registry registry;
   547     if ((r=nr_c2ru_make_registry(base, name, registry)))
   548       ABORT(r);
   550     if (r=NR_reg_get_child_registry(registry, i, child))
   551       ABORT(r);
   553     _status=0;
   554   abort:
   555     return(_status);
   556   }
   559 /* requires parent already in legal form */
   560 int
   561 NR_reg_make_registry(NR_registry parent, char *child, NR_registry out)
   562 {
   563     int r, _status;
   564     int plen;
   565     int clen;
   566     char *c;
   567     int i;
   569     if ((r=nr_reg_is_valid(parent)))
   570         ABORT(r);
   572     if (*child == '.')
   573         ABORT(R_BAD_ARGS);
   575     plen = strlen(parent);
   576     clen = strlen(child);
   577     if ((plen + clen + 2) > sizeof(NR_registry))
   578         ABORT(R_BAD_ARGS);
   580     if (out != parent)
   581         strcpy(out, parent);
   583     c = &(out[plen]);
   585     if (parent[0] != '\0') {
   586         *c = '.';
   587         ++c;
   588     }
   590     for (i = 0; i < clen; ++i, ++c) {
   591         *c = child[i];
   592         if (isspace(*c) || *c == '.' || *c == '/' || ! isprint(*c))
   593             *c = '_';
   594     }
   595     if (i == 0 || child[i-1] == '.')
   596         ABORT(R_BAD_ARGS);
   598     *c = '\0';
   600     _status = 0;
   601 abort:
   602     return _status;
   603 }

mercurial