Blame tests/gpg/t-gpgconf.c

Packit d7e8d0
/* t-gpgconf.c - Regression test.
Packit Service 30b792
 * Copyright (C) 2001, 2004, 2007 g10 Code GmbH
Packit Service 30b792
 *
Packit Service 30b792
 * This file is part of GPGME.
Packit Service 30b792
 *
Packit Service 30b792
 * GPGME is free software; you can redistribute it and/or modify it
Packit Service 30b792
 * under the terms of the GNU Lesser General Public License as
Packit Service 30b792
 * published by the Free Software Foundation; either version 2.1 of
Packit Service 30b792
 * the License, or (at your option) any later version.
Packit Service 30b792
 *
Packit Service 30b792
 * GPGME is distributed in the hope that it will be useful, but
Packit Service 30b792
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 30b792
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 30b792
 * Lesser General Public License for more details.
Packit Service 30b792
 *
Packit Service 30b792
 * You should have received a copy of the GNU Lesser General Public
Packit Service 30b792
 * License along with this program; if not, see <https://gnu.org/licenses/>.
Packit Service 30b792
 * SPDX-License-Identifier: LGPL-2.1-or-later
Packit Service 30b792
 */
Packit d7e8d0
Packit d7e8d0
#ifdef HAVE_CONFIG_H
Packit d7e8d0
#include <config.h>
Packit d7e8d0
#endif
Packit d7e8d0
Packit d7e8d0
#include <unistd.h>
Packit d7e8d0
#include <errno.h>
Packit d7e8d0
#include <stdlib.h>
Packit d7e8d0
#include <locale.h>
Packit d7e8d0
#include <string.h>
Packit d7e8d0
Packit d7e8d0
#ifdef HAVE_W32_SYSTEM
Packit d7e8d0
#include <windows.h>
Packit d7e8d0
#endif
Packit d7e8d0
Packit d7e8d0
#include <gpgme.h>
Packit d7e8d0
Packit d7e8d0
#include "t-support.h"
Packit d7e8d0

Packit d7e8d0
static char *
Packit d7e8d0
spaces (char *str, int extra)
Packit d7e8d0
{
Packit d7e8d0
  static char buf[80];
Packit d7e8d0
  int len = str ? strlen (str) : 0;
Packit d7e8d0
  int n;
Packit d7e8d0
Packit d7e8d0
#define TABSTOP 30
Packit d7e8d0
  n = TABSTOP - len - extra;
Packit d7e8d0
Packit d7e8d0
  memset (buf, ' ', sizeof (buf));
Packit d7e8d0
  if (n < 1 || n > (sizeof (buf) - 1))
Packit d7e8d0
    {
Packit d7e8d0
      buf[0] = '\n';
Packit d7e8d0
      n = TABSTOP + 1;
Packit d7e8d0
    }
Packit d7e8d0
Packit d7e8d0
  buf[n] = '\0';
Packit d7e8d0
  return buf;
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
void
Packit d7e8d0
dump_arg (int type, gpgme_conf_arg_t arg)
Packit d7e8d0
{
Packit d7e8d0
  if (!arg)
Packit d7e8d0
    {
Packit d7e8d0
      printf ("(none)");
Packit d7e8d0
      return;
Packit d7e8d0
    }
Packit d7e8d0
Packit d7e8d0
  while (arg)
Packit d7e8d0
    {
Packit d7e8d0
      switch (type)
Packit d7e8d0
	{
Packit d7e8d0
	case GPGME_CONF_STRING:
Packit d7e8d0
	case GPGME_CONF_PATHNAME:
Packit d7e8d0
	case GPGME_CONF_LDAP_SERVER:
Packit d7e8d0
        case GPGME_CONF_KEY_FPR:
Packit d7e8d0
        case GPGME_CONF_PUB_KEY:
Packit d7e8d0
        case GPGME_CONF_SEC_KEY:
Packit d7e8d0
        case GPGME_CONF_ALIAS_LIST:
Packit d7e8d0
	  printf ("`%s'", arg->value.string);
Packit d7e8d0
	  break;
Packit d7e8d0
Packit d7e8d0
	case GPGME_CONF_UINT32:
Packit d7e8d0
	  printf ("%u", arg->value.uint32);
Packit d7e8d0
	  break;
Packit d7e8d0
Packit d7e8d0
	case GPGME_CONF_INT32:
Packit d7e8d0
	  printf ("%i", arg->value.int32);
Packit d7e8d0
	  break;
Packit d7e8d0
Packit d7e8d0
	case GPGME_CONF_NONE:
Packit d7e8d0
	  printf ("%i (times)", arg->value.count);
Packit d7e8d0
	  break;
Packit d7e8d0
Packit d7e8d0
	default:
Packit d7e8d0
	  printf ("(unknown type)");
Packit d7e8d0
	}
Packit d7e8d0
Packit d7e8d0
      arg = arg->next;
Packit d7e8d0
      if (arg)
Packit d7e8d0
	printf (" ");
Packit d7e8d0
    }
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
void
Packit d7e8d0
dump_opt (gpgme_conf_opt_t opt)
Packit d7e8d0
{
Packit d7e8d0
  char level;
Packit d7e8d0
  char runtime = (opt->flags & GPGME_CONF_RUNTIME) ? 'r' : ' ';
Packit d7e8d0
Packit d7e8d0
  switch (opt->level)
Packit d7e8d0
    {
Packit d7e8d0
    case GPGME_CONF_BASIC:
Packit d7e8d0
      level = 'b';
Packit d7e8d0
      break;
Packit d7e8d0
    case GPGME_CONF_ADVANCED:
Packit d7e8d0
      level = 'a';
Packit d7e8d0
      break;
Packit d7e8d0
    case GPGME_CONF_EXPERT:
Packit d7e8d0
      level = 'e';
Packit d7e8d0
      break;
Packit d7e8d0
    case GPGME_CONF_INVISIBLE:
Packit d7e8d0
      level = 'i';
Packit d7e8d0
      break;
Packit d7e8d0
    case GPGME_CONF_INTERNAL:
Packit d7e8d0
      level = '#';
Packit d7e8d0
      break;
Packit d7e8d0
    default:
Packit d7e8d0
      level = '?';
Packit d7e8d0
    }
Packit d7e8d0
Packit d7e8d0
  if (opt->flags & GPGME_CONF_GROUP)
Packit d7e8d0
    {
Packit d7e8d0
      printf ("\n");
Packit d7e8d0
      printf ("%c%c [%s]%s%s\n", level, runtime, opt->name, spaces (opt->name, 5),
Packit d7e8d0
	      opt->description
Packit d7e8d0
	      ? opt->description : "");
Packit d7e8d0
    }
Packit d7e8d0
  else
Packit d7e8d0
    {
Packit d7e8d0
      if (opt->argname)
Packit d7e8d0
	{
Packit d7e8d0
	  const char *more = (opt->flags & GPGME_CONF_LIST) ? "..." : "";
Packit d7e8d0
Packit d7e8d0
	  if (opt->flags & GPGME_CONF_OPTIONAL)
Packit d7e8d0
	    {
Packit d7e8d0
	      printf ("%c%c --%s [%s%s] %s", level, runtime, opt->name, opt->argname, more,
Packit d7e8d0
		      spaces (opt->name, 9 + strlen (opt->argname) + strlen (more)));
Packit d7e8d0
	    }
Packit d7e8d0
	  else
Packit d7e8d0
	    {
Packit d7e8d0
	      printf ("%c%c --%s %s%s %s", level, runtime, opt->name, opt->argname, more,
Packit d7e8d0
		      spaces (opt->name, 7 + strlen (opt->argname) + strlen (more)));
Packit d7e8d0
	    }
Packit d7e8d0
	}
Packit d7e8d0
      else
Packit d7e8d0
	printf ("%c%c --%s%s", level, runtime, opt->name, spaces (opt->name, 5));
Packit d7e8d0
Packit d7e8d0
      if (opt->description)
Packit d7e8d0
	printf ("%s", opt->description);
Packit d7e8d0
      printf ("\n");
Packit d7e8d0
Packit d7e8d0
      if (opt->flags & GPGME_CONF_DEFAULT)
Packit d7e8d0
	{
Packit d7e8d0
	  printf ("%s%s = ", spaces (NULL, 0), opt->argname ? opt->argname : "(default)");
Packit d7e8d0
	  dump_arg (opt->type, opt->default_value);
Packit d7e8d0
	  printf ("\n");
Packit d7e8d0
	}
Packit d7e8d0
      else if (opt->flags & GPGME_CONF_DEFAULT_DESC)
Packit d7e8d0
	printf ("%s%s = %s\n", spaces (NULL, 0), opt->argname ? opt->argname : "(default)",
Packit d7e8d0
		opt->default_description);
Packit d7e8d0
Packit d7e8d0
      if (opt->no_arg_value)
Packit d7e8d0
	{
Packit d7e8d0
	  printf ("%sNo Arg Def = ", spaces (NULL, 0));
Packit d7e8d0
	  dump_arg (opt->type, opt->no_arg_value);
Packit d7e8d0
	  printf ("\n");
Packit d7e8d0
	}
Packit d7e8d0
      if (opt->value)
Packit d7e8d0
	{
Packit d7e8d0
	  printf ("%sCurrent = ", spaces (NULL, 0));
Packit d7e8d0
	  dump_arg (opt->type, opt->value);
Packit d7e8d0
	  printf ("\n");
Packit d7e8d0
	}
Packit d7e8d0
    }
Packit d7e8d0
Packit d7e8d0
#if 0
Packit d7e8d0
  arg = comp->options;
Packit d7e8d0
  while (opt)
Packit d7e8d0
    {
Packit d7e8d0
      dump_opt (opt);
Packit d7e8d0
      opt = opt->next;
Packit d7e8d0
    }
Packit d7e8d0
#endif
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
void
Packit d7e8d0
dump_comp (gpgme_conf_comp_t comp)
Packit d7e8d0
{
Packit d7e8d0
  gpgme_conf_opt_t opt;
Packit d7e8d0
Packit d7e8d0
  printf ("COMPONENT\n");
Packit d7e8d0
  printf ("=========\n");
Packit d7e8d0
  printf ("  Name: %s\n", comp->name);
Packit d7e8d0
  if (comp->description)
Packit d7e8d0
    printf ("  Desc: %s\n", comp->description);
Packit d7e8d0
  if (comp->program_name)
Packit d7e8d0
    printf ("  Path: %s\n", comp->program_name);
Packit d7e8d0
  printf ("\n");
Packit d7e8d0
Packit d7e8d0
  opt = comp->options;
Packit d7e8d0
  while (opt)
Packit d7e8d0
    {
Packit d7e8d0
      dump_opt (opt);
Packit d7e8d0
      opt = opt->next;
Packit d7e8d0
    }
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
int
Packit d7e8d0
lookup (gpgme_conf_comp_t conf,
Packit d7e8d0
	const char *component,
Packit d7e8d0
	const char *option,
Packit d7e8d0
	gpgme_conf_comp_t *comp,
Packit d7e8d0
	gpgme_conf_opt_t *opt)
Packit d7e8d0
{
Packit d7e8d0
  *comp = conf;
Packit d7e8d0
  while (*comp && strcmp ((*comp)->name, component))
Packit d7e8d0
    *comp = (*comp)->next;
Packit d7e8d0
Packit d7e8d0
  if (*comp)
Packit d7e8d0
    {
Packit d7e8d0
      *opt = (*comp)->options;
Packit d7e8d0
      while (*opt && strcmp ((*opt)->name, option))
Packit d7e8d0
	*opt = (*opt)->next;
Packit d7e8d0
Packit d7e8d0
      /* Allow for the option not to be there.  */
Packit d7e8d0
      if (*opt)
Packit d7e8d0
	return 1;	/* Found.  */
Packit d7e8d0
    }
Packit d7e8d0
Packit d7e8d0
  return 0;		/* Not found.  */
Packit d7e8d0
}
Packit d7e8d0
Packit d7e8d0
#include <assert.h>
Packit d7e8d0
Packit d7e8d0
Packit d7e8d0
int
Packit d7e8d0
main (void)
Packit d7e8d0
{
Packit d7e8d0
  gpgme_ctx_t ctx;
Packit d7e8d0
  gpgme_error_t err;
Packit d7e8d0
  gpgme_conf_comp_t conf;
Packit d7e8d0
  gpgme_conf_comp_t comp;
Packit d7e8d0
  int first;
Packit d7e8d0
  int i, N = 10;
Packit d7e8d0
Packit d7e8d0
  init_gpgme (GPGME_PROTOCOL_GPGCONF);
Packit d7e8d0
Packit d7e8d0
  err = gpgme_new (&ctx;;
Packit d7e8d0
  fail_if_err (err);
Packit d7e8d0
Packit d7e8d0
  {
Packit d7e8d0
    /* Let's check getting the agent-socket directory for different homedirs.  */
Packit d7e8d0
    char *result1 = NULL;
Packit d7e8d0
    char *result2 = NULL;
Packit d7e8d0
    err = gpgme_ctx_set_engine_info (ctx, GPGME_PROTOCOL_GPGCONF, NULL, "/tmp/foo");
Packit d7e8d0
    fail_if_err (err);
Packit d7e8d0
    err = gpgme_op_conf_dir (ctx, "agent-socket", &result1);
Packit d7e8d0
    fail_if_err (err);
Packit d7e8d0
Packit d7e8d0
    err = gpgme_ctx_set_engine_info (ctx, GPGME_PROTOCOL_GPGCONF, NULL, NULL);
Packit d7e8d0
    fail_if_err (err);
Packit d7e8d0
    err = gpgme_op_conf_dir (ctx, "agent-socket", &result2);
Packit d7e8d0
    fail_if_err (err);
Packit d7e8d0
Packit d7e8d0
    /* They have to be different.  */
Packit d7e8d0
    test (strcmp(result1, result2));
Packit d7e8d0
    gpgme_free (result1);
Packit d7e8d0
    gpgme_free (result2);
Packit d7e8d0
  }
Packit d7e8d0
Packit d7e8d0
  err = gpgme_op_conf_load (ctx, &conf;;
Packit d7e8d0
  fail_if_err (err);
Packit d7e8d0
Packit d7e8d0
  comp = conf;
Packit d7e8d0
  first = 1;
Packit d7e8d0
  while (comp)
Packit d7e8d0
    {
Packit d7e8d0
      if (!first)
Packit d7e8d0
	printf ("\n");
Packit d7e8d0
      else
Packit d7e8d0
	first = 0;
Packit d7e8d0
      dump_comp (comp);
Packit d7e8d0
      comp = comp->next;
Packit d7e8d0
    }
Packit d7e8d0
Packit d7e8d0
  /* Now change something.  */
Packit d7e8d0
  fprintf (stderr, " dirmngr.verbose ");
Packit d7e8d0
  for (i = 0; i < N; i++) {
Packit d7e8d0
    unsigned int count = i % 4 + 1; /* counts must not be zero */
Packit d7e8d0
    gpgme_conf_arg_t arg;
Packit d7e8d0
    gpgme_conf_opt_t opt;
Packit d7e8d0
Packit d7e8d0
    err = gpgme_conf_arg_new (&arg, GPGME_CONF_NONE, &count);
Packit d7e8d0
    fail_if_err (err);
Packit d7e8d0
Packit d7e8d0
    if (lookup (conf, "dirmngr", "verbose", &comp, &opt))
Packit d7e8d0
      {
Packit d7e8d0
	/* Found.  */
Packit d7e8d0
	err = gpgme_conf_opt_change (opt, 0, arg);
Packit d7e8d0
	fail_if_err (err);
Packit d7e8d0
Packit d7e8d0
	err = gpgme_op_conf_save (ctx, comp);
Packit d7e8d0
	fail_if_err (err);
Packit d7e8d0
      }
Packit d7e8d0
    else
Packit d7e8d0
      {
Packit d7e8d0
	fprintf (stderr, "Skipping test, option dirmngr.verbose not found.\n");
Packit d7e8d0
	break;
Packit d7e8d0
      }
Packit d7e8d0
Packit d7e8d0
    /* Reload config and verify that the value was updated.  */
Packit d7e8d0
    gpgme_conf_release (conf);
Packit d7e8d0
    err = gpgme_op_conf_load (ctx, &conf;;
Packit d7e8d0
    fail_if_err (err);
Packit d7e8d0
    if (lookup (conf, "dirmngr", "verbose", &comp, &opt))
Packit d7e8d0
      {
Packit d7e8d0
        /* Found.  */
Packit d7e8d0
        test (opt->alt_type == GPGME_CONF_NONE);
Packit d7e8d0
        test (opt->value);
Packit d7e8d0
        test ((unsigned long) opt->value->value.count == count);
Packit d7e8d0
      }
Packit d7e8d0
Packit d7e8d0
    fprintf (stderr, ".");
Packit d7e8d0
    fflush (stderr);
Packit d7e8d0
  }
Packit d7e8d0
Packit d7e8d0
  /* Now change something else.  */
Packit d7e8d0
  fprintf (stderr, " gpg.keyserver ");
Packit d7e8d0
  for (i = 0; i < N; i++) {
Packit d7e8d0
    const char *values[2] = { "hkp://foo.bar", "hkps://bar.foo" };
Packit d7e8d0
    gpgme_conf_arg_t arg;
Packit d7e8d0
    gpgme_conf_opt_t opt;
Packit d7e8d0
Packit d7e8d0
    err = gpgme_conf_arg_new (&arg, GPGME_CONF_STRING, values[i%2]);
Packit d7e8d0
    fail_if_err (err);
Packit d7e8d0
Packit d7e8d0
    if (lookup (conf, "gpg", "keyserver", &comp, &opt))
Packit d7e8d0
      {
Packit d7e8d0
	/* Found.  */
Packit d7e8d0
	test (opt->alt_type == GPGME_CONF_STRING);
Packit d7e8d0
	err = gpgme_conf_opt_change (opt, 0, arg);
Packit d7e8d0
	fail_if_err (err);
Packit d7e8d0
Packit d7e8d0
	err = gpgme_op_conf_save (ctx, comp);
Packit d7e8d0
	fail_if_err (err);
Packit d7e8d0
      }
Packit d7e8d0
    else
Packit d7e8d0
      {
Packit d7e8d0
	fprintf (stderr, "Skipping test, option gpg.keyserver not found.\n");
Packit d7e8d0
	break;
Packit d7e8d0
      }
Packit d7e8d0
Packit d7e8d0
    /* Reload config and verify that the value was updated.  */
Packit d7e8d0
    gpgme_conf_release (conf);
Packit d7e8d0
    err = gpgme_op_conf_load (ctx, &conf;;
Packit d7e8d0
    fail_if_err (err);
Packit d7e8d0
    if (lookup (conf, "gpg", "keyserver", &comp, &opt))
Packit d7e8d0
      {
Packit d7e8d0
        /* Found.  */
Packit d7e8d0
        test (opt->alt_type == GPGME_CONF_STRING);
Packit d7e8d0
        test (opt->value);
Packit d7e8d0
        test (opt->value->value.string);
Packit d7e8d0
        test (strcmp (opt->value->value.string, values[i%2]) == 0);
Packit d7e8d0
      }
Packit d7e8d0
Packit d7e8d0
    fprintf (stderr, ".");
Packit d7e8d0
    fflush (stderr);
Packit d7e8d0
  }
Packit d7e8d0
  fprintf (stderr, "\n");
Packit d7e8d0
Packit d7e8d0
  gpgme_conf_release (conf);
Packit d7e8d0
  gpgme_release (ctx);
Packit d7e8d0
  return 0;
Packit d7e8d0
}