LCOV - code coverage report
Current view: top level - src - assuan.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 70 100 70.0 %
Date: 2015-11-05 17:06:03 Functions: 8 15 53.3 %

          Line data    Source code
       1             : /* assuan.c - Global interface (not specific to context).
       2             :    Copyright (C) 2009 Free Software Foundation, Inc.
       3             :    Copyright (C) 2001, 2002, 2012, 2013 g10 Code GmbH
       4             : 
       5             :    This file is part of Assuan.
       6             : 
       7             :    Assuan is free software; you can redistribute it and/or modify it
       8             :    under the terms of the GNU Lesser General Public License as
       9             :    published by the Free Software Foundation; either version 2.1 of
      10             :    the License, or (at your option) any later version.
      11             : 
      12             :    Assuan is distributed in the hope that it will be useful, but
      13             :    WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :    Lesser General Public License for more details.
      16             : 
      17             :    You should have received a copy of the GNU Lesser General Public
      18             :    License along with this program; if not, see <http://www.gnu.org/licenses/>.
      19             :  */
      20             : 
      21             : 
      22             : #ifdef HAVE_CONFIG_H
      23             : #include <config.h>
      24             : #endif
      25             : 
      26             : #include <stdlib.h>
      27             : 
      28             : #include "assuan-defs.h"
      29             : #include "debug.h"
      30             : 
      31             : 
      32             : #define digitp(a) ((a) >= '0' && (a) <= '9')
      33             : 
      34             : 
      35             : 
      36             : /* Global default state.  */
      37             : 
      38             : /* The default error source gor generated error codes.  */
      39             : static gpg_err_source_t _assuan_default_err_source = GPG_ERR_SOURCE_USER_1;
      40             : 
      41             : /* The default memory management functions.  */
      42             : static struct assuan_malloc_hooks _assuan_default_malloc_hooks =
      43             :   { malloc, realloc, free };
      44             : 
      45             : /* The default logging handler.  */
      46             : static assuan_log_cb_t _assuan_default_log_cb = _assuan_log_handler;
      47             : static void *_assuan_default_log_cb_data = NULL;
      48             : 
      49             : 
      50             : /* Set the default gpg error source.  */
      51             : void
      52           0 : assuan_set_gpg_err_source (gpg_err_source_t errsource)
      53             : {
      54           0 :   _assuan_default_err_source = errsource;
      55           0 : }
      56             : 
      57             : 
      58             : /* Get the default gpg error source.  */
      59             : gpg_err_source_t
      60           0 : assuan_get_gpg_err_source (void)
      61             : {
      62           0 :   return _assuan_default_err_source;
      63             : }
      64             : 
      65             : 
      66             : /* Set the default malloc hooks.  */
      67             : void
      68           0 : assuan_set_malloc_hooks (assuan_malloc_hooks_t malloc_hooks)
      69             : {
      70           0 :   _assuan_default_malloc_hooks = *malloc_hooks;
      71           0 : }
      72             : 
      73             : 
      74             : /* Get the default malloc hooks.  */
      75             : assuan_malloc_hooks_t
      76           0 : assuan_get_malloc_hooks (void)
      77             : {
      78           0 :   return &_assuan_default_malloc_hooks;
      79             : }
      80             : 
      81             : 
      82             : /* Set the default log callback handler.  */
      83             : void
      84           0 : assuan_set_log_cb (assuan_log_cb_t log_cb, void *log_cb_data)
      85             : {
      86           0 :   _assuan_default_log_cb = log_cb;
      87           0 :   _assuan_default_log_cb_data = log_cb_data;
      88           0 :   _assuan_init_log_envvars ();
      89           0 : }
      90             : 
      91             : 
      92             : /* Get the default log callback handler.  */
      93             : void
      94           0 : assuan_get_log_cb (assuan_log_cb_t *log_cb, void **log_cb_data)
      95             : {
      96           0 :   *log_cb = _assuan_default_log_cb;
      97           0 :   *log_cb_data = _assuan_default_log_cb_data;
      98           0 : }
      99             : 
     100             : 
     101             : void
     102           0 : assuan_set_system_hooks (assuan_system_hooks_t system_hooks)
     103             : {
     104           0 :   _assuan_system_hooks_copy (&_assuan_system_hooks, system_hooks);
     105           0 : }
     106             : 
     107             : 
     108             : /* Create a new Assuan context.  The initial parameters are all needed
     109             :    in the creation of the context.  */
     110             : gpg_error_t
     111           6 : assuan_new_ext (assuan_context_t *r_ctx, gpg_err_source_t err_source,
     112             :                 assuan_malloc_hooks_t malloc_hooks, assuan_log_cb_t log_cb,
     113             :                 void *log_cb_data)
     114             : {
     115             :   struct assuan_context_s wctx;
     116             :   assuan_context_t ctx;
     117             : 
     118             :   /* Set up a working context so we can use standard functions.  */
     119           6 :   memset (&wctx, 0, sizeof (wctx));
     120           6 :   wctx.err_source = err_source;
     121           6 :   wctx.malloc_hooks = *malloc_hooks;
     122           6 :   wctx.log_cb = log_cb;
     123           6 :   wctx.log_cb_data = log_cb_data;
     124             : 
     125             :   /* Need a new block for the trace macros to work.  */
     126             :   {
     127           6 :     TRACE_BEG8 (&wctx, ASSUAN_LOG_CTX, "assuan_new_ext", r_ctx,
     128             :                 "err_source = %i (%s), malloc_hooks = %p (%p, %p, %p), "
     129             :                 "log_cb = %p, log_cb_data = %p", err_source,
     130             :                 gpg_strsource (err_source), malloc_hooks, malloc_hooks->malloc,
     131             :                 malloc_hooks->realloc, malloc_hooks->free, log_cb, log_cb_data);
     132             : 
     133           6 :     *r_ctx = NULL;
     134           6 :     ctx = _assuan_malloc (&wctx, sizeof (*ctx));
     135           6 :     if (!ctx)
     136           0 :       return TRACE_ERR (gpg_err_code_from_syserror ());
     137             : 
     138           6 :     memcpy (ctx, &wctx, sizeof (*ctx));
     139           6 :     ctx->system = _assuan_system_hooks;
     140             : 
     141             :     /* FIXME: Delegate to subsystems/engines, as the FDs are not our
     142             :        responsibility (we don't deallocate them, for example).  */
     143           6 :     ctx->input_fd = ASSUAN_INVALID_FD;
     144           6 :     ctx->output_fd = ASSUAN_INVALID_FD;
     145           6 :     ctx->inbound.fd = ASSUAN_INVALID_FD;
     146           6 :     ctx->outbound.fd = ASSUAN_INVALID_FD;
     147           6 :     ctx->listen_fd = ASSUAN_INVALID_FD;
     148             : 
     149           6 :     *r_ctx = ctx;
     150             : 
     151           6 :     return TRACE_SUC1 ("ctx=%p", ctx);
     152             :   }
     153             : }
     154             : 
     155             : 
     156             : /* Create a new context with default arguments.  */
     157             : gpg_error_t
     158           6 : assuan_new (assuan_context_t *r_ctx)
     159             : {
     160           6 :   return assuan_new_ext (r_ctx, _assuan_default_err_source,
     161             :                          &_assuan_default_malloc_hooks,
     162             :                          _assuan_default_log_cb,
     163             :                          _assuan_default_log_cb_data);
     164             : }
     165             : 
     166             : 
     167             : /* Release all resources associated with an engine operation.  */
     168             : void
     169           4 : _assuan_reset (assuan_context_t ctx)
     170             : {
     171           4 :   if (ctx->engine.release)
     172             :     {
     173           4 :       (*ctx->engine.release) (ctx);
     174           4 :       ctx->engine.release = NULL;
     175             :     }
     176             : 
     177             :   /* FIXME: Clean standard commands */
     178           4 : }
     179             : 
     180             : 
     181             : /* Release all resources associated with the given context.  */
     182             : void
     183           4 : assuan_release (assuan_context_t ctx)
     184             : {
     185           4 :   if (! ctx)
     186           4 :     return;
     187             : 
     188           4 :   TRACE (ctx, ASSUAN_LOG_CTX, "assuan_release", ctx);
     189             : 
     190           4 :   _assuan_reset (ctx);
     191             :   /* None of the members that are our responsibility requires
     192             :      deallocation.  To avoid sensitive data in the line buffers we
     193             :      wipe them out, though.  Note that we can't wipe the entire
     194             :      context because it also has a pointer to the actual free().  */
     195           4 :   wipememory (&ctx->inbound, sizeof ctx->inbound);
     196           4 :   wipememory (&ctx->outbound, sizeof ctx->outbound);
     197           4 :   _assuan_free (ctx, ctx);
     198             : }
     199             : 
     200             : 
     201             : 
     202             : /*
     203             :     Version number stuff.
     204             :  */
     205             : 
     206             : static const char*
     207          16 : parse_version_number (const char *s, int *number)
     208             : {
     209          16 :   int val = 0;
     210             : 
     211          16 :   if (*s == '0' && digitp (s[1]))
     212           0 :     return NULL;  /* Leading zeros are not allowed.  */
     213          34 :   for (; digitp (*s); s++)
     214             :     {
     215          18 :       val *= 10;
     216          18 :       val += *s - '0';
     217             :     }
     218          16 :   *number = val;
     219          16 :   return val < 0 ? NULL : s;
     220             : }
     221             : 
     222             : 
     223             : static const char *
     224           6 : parse_version_string (const char *s, int *major, int *minor, int *micro)
     225             : {
     226           6 :   s = parse_version_number (s, major);
     227           6 :   if (!s || *s != '.')
     228           1 :     return NULL;
     229           5 :   s++;
     230           5 :   s = parse_version_number (s, minor);
     231           5 :   if (!s || *s != '.')
     232           0 :     return NULL;
     233           5 :   s++;
     234           5 :   s = parse_version_number (s, micro);
     235           5 :   if (!s)
     236           0 :     return NULL;
     237           5 :   return s;  /* Patchlevel.  */
     238             : }
     239             : 
     240             : 
     241             : static const char *
     242           3 : compare_versions (const char *my_version, const char *req_version)
     243             : {
     244             :   int my_major, my_minor, my_micro;
     245             :   int rq_major, rq_minor, rq_micro;
     246             :   const char *my_plvl, *rq_plvl;
     247             : 
     248           3 :   if (!req_version)
     249           0 :     return my_version;
     250           3 :   if (!my_version)
     251           0 :     return NULL;
     252             : 
     253           3 :   my_plvl = parse_version_string (my_version, &my_major, &my_minor, &my_micro);
     254           3 :   if (!my_plvl)
     255           0 :     return NULL;        /* Very strange: our own version is bogus.  */
     256           3 :   rq_plvl = parse_version_string(req_version,
     257             :                                  &rq_major, &rq_minor, &rq_micro);
     258           3 :   if (!rq_plvl)
     259           1 :     return NULL;        /* Requested version string is invalid.  */
     260             : 
     261           2 :   if (my_major > rq_major
     262           2 :         || (my_major == rq_major && my_minor > rq_minor)
     263           1 :       || (my_major == rq_major && my_minor == rq_minor
     264           1 :           && my_micro > rq_micro)
     265           1 :       || (my_major == rq_major && my_minor == rq_minor
     266           1 :           && my_micro == rq_micro))
     267             :     {
     268           2 :       return my_version;
     269             :     }
     270           0 :   return NULL;
     271             : }
     272             : 
     273             : 
     274             : /*
     275             :  * Check that the the version of the library is at minimum REQ_VERSION
     276             :  * and return the actual version string; return NULL if the condition
     277             :  * is not met.  If NULL is passed to this function, no check is done
     278             :  * and the version string is simply returned.
     279             :  */
     280             : const char *
     281           3 : assuan_check_version (const char *req_version)
     282             : {
     283           3 :   return compare_versions (PACKAGE_VERSION, req_version);
     284             : }

Generated by: LCOV version 1.11