コード例 #1
0
ファイル: pinentry.cpp プロジェクト: Hangman-65/Freecoin
Pin::Pin() {
  gpg_error_t res;
  pid_t pid;
  int flags;
  const char *argv[2];

  gpg_err_init();
  res = assuan_new (&ctx);
  if(res)
    throw runtime_error(strprintf("pinentry initialisation: %s", gpg_strerror(res)));

  assuan_set_assuan_log_prefix("Pin: ");

  // needed esp. for ncurses
  lang = strprintf("OPTION lc-ctype=%s",getenv("LANG"));
  tty = strprintf("OPTION ttyname=%s",getenv("TTY"));

  flags = 0x0;
  argv[0] = "bitcoind"; // fake argv
  argv[1] = NULL;
  res = assuan_pipe_connect (ctx, SECURE_EXEC_PATH"/pinentry",
			     argv, NULL, NULL, NULL, flags);
  if(res)
    throw runtime_error(strprintf("pinentry pipe forking: %s", gpg_strerror(res)));

  pid = assuan_get_pid(ctx);
  if(pid == ASSUAN_INVALID_PID)
    throw runtime_error(strprintf("pinentry not running: %s", gpg_strerror(res)));

  cmd(tty.c_str());
  cmd(lang.c_str());
}
コード例 #2
0
ファイル: fdpassing.c プロジェクト: cobaugh/rt-rpm
/* 
 
     M A I N

*/
int 
main (int argc, char **argv)
{
  int last_argc = -1;
  assuan_context_t ctx;
  gpg_error_t err;
  int no_close_fds[2];
  const char *arglist[10];
  int is_server = 0;
  int with_exec = 0;
  char *fname = prepend_srcdir ("motd");

  if (argc)
    {
      log_set_prefix (*argv);
      argc--; argv++;
    }
  while (argc && last_argc != argc )
    {
      last_argc = argc;
      if (!strcmp (*argv, "--help"))
        {
          puts (
"usage: ./fdpassing [options]\n"
"\n"
"Options:\n"
"  --verbose      Show what is going on\n"
"  --with-exec    Exec the child.  Default is just a fork\n"
);
          exit (0);
        }
      if (!strcmp (*argv, "--verbose"))
        {
          verbose = 1;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--debug"))
        {
          verbose = debug = 1;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--server"))
        {
          is_server = 1;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--with-exec"))
        {
          with_exec = 1;
          argc--; argv++;
        }
    }


  assuan_set_assuan_log_prefix (log_prefix);

  if (is_server)
    {
      server ();
      log_info ("server finished\n");
    }
  else
    {
      const char *loc;

      no_close_fds[0] = 2;
      no_close_fds[1] = -1;
      if (with_exec)
        {
          arglist[0] = "fdpassing";
          arglist[1] = "--server";
          arglist[2] = verbose? "--verbose":NULL;
          arglist[3] = NULL;
        }

      err = assuan_new (&ctx);
      if (err)
	log_fatal ("assuan_new failed: %s\n", gpg_strerror (err));

      err = assuan_pipe_connect (ctx, with_exec? "./fdpassing":NULL,
				 with_exec ? arglist : &loc,
				 no_close_fds, NULL, NULL, 1);
      if (err)
        {
          log_error ("assuan_pipe_connect failed: %s\n", gpg_strerror (err));
          return 1;
        }
      
      if (!with_exec && loc[0] == 's')
        {
          server ();
          log_info ("server finished\n");
        }
      else
        {
          if (client (ctx, fname)) 
            {
              log_info ("waiting for server to terminate...\n");
              assuan_release (ctx);
            }
          log_info ("client finished\n");
        }
    }

  return errorcount ? 1 : 0;
}
コード例 #3
0
ファイル: dirmngr-client.c プロジェクト: Domikk/gnupg
int
main (int argc, char **argv )
{
  ARGPARSE_ARGS pargs;
  assuan_context_t ctx;
  gpg_error_t err;
  unsigned char *certbuf;
  size_t certbuflen = 0;
  int cmd_ping = 0;
  int cmd_cache_cert = 0;
  int cmd_validate = 0;
  int cmd_lookup = 0;
  int cmd_loadcrl = 0;
  int cmd_squid_mode = 0;

  set_strusage (my_strusage);
  log_set_prefix ("dirmngr-client",
                  JNLIB_LOG_WITH_PREFIX);

  /* For W32 we need to initialize the socket subsystem.  Becuase we
     don't use Pth we need to do this explicit. */
#ifdef HAVE_W32_SYSTEM
 {
   WSADATA wsadat;

   WSAStartup (0x202, &wsadat);
 }
#endif /*HAVE_W32_SYSTEM*/

  /* Init Assuan.  */
  assuan_set_assuan_log_prefix (log_get_prefix (NULL));
  assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);

  /* Setup I18N. */
  i18n_init();

  /* Parse the command line.  */
  pargs.argc = &argc;
  pargs.argv = &argv;
  pargs.flags= 1;  /* Do not remove the args. */
  while (arg_parse (&pargs, opts) )
    {
      switch (pargs.r_opt)
        {
        case oVerbose: opt.verbose++; break;
        case oQuiet: opt.quiet++; break;

        case oOCSP: opt.use_ocsp++; break;
        case oPing: cmd_ping = 1; break;
        case oCacheCert: cmd_cache_cert = 1; break;
        case oValidate: cmd_validate = 1; break;
        case oLookup: cmd_lookup = 1; break;
        case oUrl: opt.url = 1; break;
        case oLocal: opt.local = 1; break;
        case oLoadCRL: cmd_loadcrl = 1; break;
        case oPEM: opt.pem = 1; break;
        case oSquidMode:
          opt.pem = 1;
          opt.escaped_pem = 1;
          cmd_squid_mode = 1;
          break;
        case oForceDefaultResponder: opt.force_default_responder = 1; break;

        default : pargs.err = 2; break;
	}
    }
  if (log_get_errorcount (0))
    exit (2);

  /* Build the helptable for radix64 to bin conversion. */
  if (opt.pem)
    {
      int i;
      unsigned char *s;

      for (i=0; i < 256; i++ )
        asctobin[i] = 255; /* Used to detect invalid characters. */
      for (s=bintoasc, i=0; *s; s++, i++)
        asctobin[*s] = i;
    }


  if (cmd_ping)
    err = 0;
  else if (cmd_lookup || cmd_loadcrl)
    {
      if (!argc)
        usage (1);
      err = 0;
    }
  else if (cmd_squid_mode)
    {
      err = 0;
      if (argc)
        usage (1);
    }
  else if (!argc)
    {
      err = read_certificate (NULL, &certbuf, &certbuflen);
      if (err)
        log_error (_("error reading certificate from stdin: %s\n"),
                   gpg_strerror (err));
    }
  else if (argc == 1)
    {
      err = read_certificate (*argv, &certbuf, &certbuflen);
      if (err)
        log_error (_("error reading certificate from '%s': %s\n"),
                   *argv, gpg_strerror (err));
    }
  else
    {
      err = 0;
      usage (1);
    }

  if (log_get_errorcount (0))
    exit (2);

  if (certbuflen > 20000)
    {
      log_error (_("certificate too large to make any sense\n"));
      exit (2);
    }

  ctx = start_dirmngr (1);
  if (!ctx)
    exit (2);

  if (cmd_ping)
    ;
  else if (cmd_squid_mode)
    {
      while (!(err = squid_loop_body (ctx)))
        ;
      if (gpg_err_code (err) == GPG_ERR_EOF)
        err = 0;
    }
  else if (cmd_lookup)
    {
      int last_err = 0;

      for (; argc; argc--, argv++)
        {
          err = do_lookup (ctx, *argv);
          if (err)
            {
              log_error (_("lookup failed: %s\n"), gpg_strerror (err));
              last_err = err;
            }
        }
      err = last_err;
    }
  else if (cmd_loadcrl)
    {
      int last_err = 0;

      for (; argc; argc--, argv++)
        {
          err = do_loadcrl (ctx, *argv);
          if (err)
            {
              log_error (_("loading CRL '%s' failed: %s\n"),
                         *argv, gpg_strerror (err));
              last_err = err;
            }
        }
      err = last_err;
    }
  else if (cmd_cache_cert)
    {
      err = do_cache (ctx, certbuf, certbuflen);
      xfree (certbuf);
    }
  else if (cmd_validate)
    {
      err = do_validate (ctx, certbuf, certbuflen);
      xfree (certbuf);
    }
  else
    {
      err = do_check (ctx, certbuf, certbuflen);
      xfree (certbuf);
    }

  assuan_release (ctx);

  if (cmd_ping)
    {
      if (!opt.quiet)
        log_info (_("a dirmngr daemon is up and running\n"));
      return 0;
    }
  else if (cmd_lookup|| cmd_loadcrl || cmd_squid_mode)
    return err? 1:0;
  else if (cmd_cache_cert)
    {
      if (err && gpg_err_code (err) == GPG_ERR_DUP_VALUE )
        {
          if (!opt.quiet)
            log_info (_("certificate already cached\n"));
        }
      else if (err)
        {
          log_error (_("error caching certificate: %s\n"),
                     gpg_strerror (err));
          return 1;
        }
      return 0;
    }
  else if (cmd_validate && err)
    {
      log_error (_("validation of certificate failed: %s\n"),
                 gpg_strerror (err));
      return 1;
    }
  else if (!err)
    {
      if (!opt.quiet)
        log_info (_("certificate is valid\n"));
      return 0;
    }
  else if (gpg_err_code (err) == GPG_ERR_CERT_REVOKED )
    {
      if (!opt.quiet)
        log_info (_("certificate has been revoked\n"));
      return 1;
    }
  else
    {
      log_error (_("certificate check failed: %s\n"), gpg_strerror (err));
      return 2;
    }
}
コード例 #4
0
int main (int argc, char *argv[])
{
	enum {
		OPT_SERVER,
		OPT_MUTLI_SERVER,
		OPT_DAEMON,
		OPT_VERBOSE,
		OPT_QUIET,
		OPT_SH,
		OPT_CSH,
		OPT_OPTIONS,
		OPT_NO_DETACH,
		OPT_LOG_FILE,
		OPT_VERSION,
		OPT_HELP
	};

	static struct option long_options[] = {
		{ "server", no_argument, NULL, OPT_SERVER },
		{ "multi-server", no_argument, NULL, OPT_MUTLI_SERVER },
		{ "daemon", no_argument, NULL, OPT_DAEMON },
		{ "verbose", no_argument, NULL, OPT_VERBOSE },
		{ "quiet", no_argument, NULL, OPT_QUIET },
		{ "sh", no_argument, NULL, OPT_SH },
		{ "csh", no_argument, NULL, OPT_CSH },
		{ "options", required_argument, NULL, OPT_OPTIONS },
		{ "no-detach", no_argument, NULL, OPT_NO_DETACH },
		{ "log-file", required_argument, NULL, OPT_LOG_FILE },
		{ "version", no_argument, NULL, OPT_VERSION },
		{ "help", no_argument, NULL, OPT_HELP },
		{ NULL, 0, NULL, 0 }
	};
	int long_options_ret;
	int base_argc = 1;

	int usage_ok = 1;
	enum {
		RUN_MODE_NONE,
		RUN_MODE_SERVER,
		RUN_MODE_MULTI_SERVER,
		RUN_MODE_DAEMON
	} run_mode = RUN_MODE_NONE;
	int env_is_csh = 0;
	int log_verbose = 0;
	int log_quiet = 0;
	int no_detach = 0;
	char *config_file = NULL;
	char *log_file = NULL;
	char *home_dir = NULL;
	int have_at_least_one_provider=0;
	FILE *fp_log = NULL;
	int i;
	CK_RV rv;

	dconfig_data_t config;

	const char * CONFIG_SUFFIX = ".conf";
	char *default_config_file = NULL;

#if !defined(HAVE_W32_SYSTEM)
	s_parent_pid = getpid ();
#endif

	if ((default_config_file = (char *)malloc (strlen (PACKAGE)+strlen (CONFIG_SUFFIX)+1)) == NULL) {
		common_log (LOG_FATAL, "malloc failed");
	}
	sprintf (default_config_file, "%s%s", PACKAGE, CONFIG_SUFFIX);

	common_set_log_stream (stderr);

	while ((long_options_ret = getopt_long (argc, argv, "vqsc", long_options, NULL)) != -1) {
		base_argc++;

		switch (long_options_ret) {
			case OPT_SERVER:
				run_mode = RUN_MODE_SERVER;
			break;
			case OPT_MUTLI_SERVER:
				run_mode = RUN_MODE_MULTI_SERVER;
			break;
			case OPT_DAEMON:
				run_mode = RUN_MODE_DAEMON;
			break;
			case OPT_VERBOSE:
			case 'v':
				log_verbose = 1;
			break;
			case OPT_QUIET:
			case 'q':
				log_quiet = 1;
			break;
			case OPT_SH:
			case 's':
			break;
			case OPT_CSH:
			case 'c':
				env_is_csh = 1;
			break;
			case OPT_OPTIONS:
				base_argc++;
				config_file = strdup (optarg);
			break;
			case OPT_NO_DETACH:
				no_detach = 1;
			break;
			case OPT_LOG_FILE:
				base_argc++;
				log_file = strdup (optarg);
			break;
			case OPT_VERSION:
				printf (
					"%s %s\n"
					"\n"
					"Copyright (c) 2006-2007 Zeljko Vrba <*****@*****.**>\n"
					"Copyright (c) 2006-2011 Alon Bar-Lev <*****@*****.**>\n"
					"\n"
					"This is free software; see the source for copying conditions.\n"
					"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
					PACKAGE,
					PACKAGE_VERSION
				);
				exit (1);
			break;
			case OPT_HELP:
				usage_ok = 0;
			break;
			default:
				usage_ok = 0;
			break;
		}
	}

	if (base_argc < argc) {
		if (!strcmp (argv[base_argc], "--")) {
			base_argc++;
		}
	}

	if (!usage_ok) {
		usage (argv[0]);
	}

	if (run_mode == RUN_MODE_NONE) {
		common_log (LOG_FATAL, "please use the option `--daemon' to run the program in the background");
	}

#if defined(HAVE_W32_SYSTEM)
	if (run_mode == RUN_MODE_DAEMON) {
		common_log (LOG_FATAL, "daemon mode is not supported");
	}
#endif

	home_dir = get_home_dir ();

	if (config_file == NULL) {
		if ((config_file = (char *)malloc (strlen (home_dir) + strlen (default_config_file)+2)) == NULL) {
			common_log (LOG_FATAL, "malloc failed");
		}
		sprintf (config_file, "%s%c%s", home_dir, CONFIG_PATH_SEPARATOR, default_config_file);
	}

	if (
		!dconfig_read (config_file, &config) &&
		!dconfig_read (CONFIG_SYSTEM_CONFIG, &config)
	) {
		common_log (LOG_FATAL, "Cannot open configuration file");
	}

	if (log_file != NULL) {
		if (config.log_file != NULL) {
			free (config.log_file);
		}
		if ((config.log_file = strdup (log_file)) == NULL) {
			common_log (LOG_FATAL, "strdup failed");
		}
	}

	if (log_verbose) {
		config.verbose = 1;
	}

#if !defined(HAVE_W32_SYSTEM)
	signal (SIGPIPE, SIG_IGN);
	signal (SIGINT, on_signal);
	signal (SIGTERM, on_signal);
	signal (SIGABRT, on_signal);
	signal (SIGHUP, on_signal);
#endif

	if (log_file != NULL) {
		if (strcmp (log_file, "stderr")) {
			if ((fp_log = fopen (log_file, "a")) != NULL) {
				common_set_log_stream (fp_log);
			}
		}
	}
	else if (config.log_file != NULL) {
		if (strcmp (config.log_file, "stderr")) {
			if ((fp_log = fopen (config.log_file, "a")) != NULL) {
				common_set_log_stream (fp_log);
			}
		}
	}

	if (config.debug) {
		common_log (LOG_DEBUG, "version: %s", PACKAGE_VERSION);
		dconfig_print (&config);
		common_log (LOG_DEBUG, "run_mode: %d", run_mode);
		common_log (LOG_DEBUG, "crypto: %s",
#if defined(ENABLE_OPENSSL)
			"openssl"
#elif defined(ENABLE_GNUTLS)
			"gnutls"
#else
			"invalid"
#endif
		);
	}

#if !defined(HAVE_W32_SYSTEM)
	if (run_mode == RUN_MODE_DAEMON || run_mode == RUN_MODE_MULTI_SERVER) {
		server_socket_create_name ();
	}

	/*
	 * fork before doing PKCS#11 stuff
	 * some providers don't behave well
	 */
	if (run_mode == RUN_MODE_DAEMON) {
		pid_t pid;

		pid = fork ();

		if (pid == -1) {
			common_log (LOG_FATAL, "fork failed");
		}

		if (pid != 0) {
			static const char *key = "SCDAEMON_INFO";
			char env[1024];
			snprintf (env, sizeof (env), "%s:%lu:1", s_socket_name, (unsigned long)pid);

			if (argc - base_argc > 0) {
				setenv(key, env, 1);
				execvp (argv[base_argc], &(argv[base_argc]));
				kill (pid, SIGTERM);
				exit (1);
			}
			else {
				if (env_is_csh) {
					*strchr (env, '=') = ' ';
					printf ("setenv %s %s\n", key, env);
				}
				else {
					printf ("%s=%s; export %s\n", key, env, key);
				}
				exit (0);
			}
		}

		if (!no_detach) {
			int i;

			for (i=0;i<3;i++) {
				if (fileno (common_get_log_stream ()) != i) {
					close (i);
				}
			}

			if (setsid () == -1) {
				common_log (LOG_FATAL, "setsid failed");
			}
		}

		if (chdir ("/") == -1) {
			common_log (LOG_FATAL, "chdir failed");
		}

		if (argc - base_argc > 0) {
			struct sigaction sa;

			memset (&sa, 0, sizeof (sa));
			sigemptyset (&sa.sa_mask);
#if defined(SA_INTERRUPT)
			sa.sa_flags |= SA_INTERRUPT;
#endif
			sa.sa_handler = on_alarm;
			sigaction (SIGALRM, &sa, NULL);
			alarm (10);
		}
	}
#endif				/* HAVE_W32_SYSTEM */

	assuan_set_assuan_log_prefix (PACKAGE);
	assuan_set_assuan_log_stream (common_get_log_stream ());

#if defined(USE_GNUTLS)
	if (gnutls_global_init () != GNUTLS_E_SUCCESS) {
		common_log (LOG_FATAL, "Cannot initialize gnutls");
	}
#endif

	if ((rv = pkcs11h_initialize ()) != CKR_OK) {
		common_log (LOG_FATAL, "Cannot initialize PKCS#11: %s", pkcs11h_getMessage (rv));
	}

	pkcs11h_setLogLevel (config.verbose ? PKCS11H_LOG_DEBUG2 : PKCS11H_LOG_INFO);
	pkcs11h_setLogHook (pkcs11_log_hook, NULL);
	pkcs11h_setTokenPromptHook (pkcs11_token_prompt_hook, NULL);
	pkcs11h_setPINPromptHook (pkcs11_pin_prompt_hook, NULL);
	pkcs11h_setProtectedAuthentication (TRUE);

	for (i=0;i<DCONFIG_MAX_PROVIDERS;i++) {
		if (
			config.providers[i].name != NULL &&
			config.providers[i].library != NULL
		) {
			if (
				(rv = pkcs11h_addProvider (
					config.providers[i].name,
					config.providers[i].library,
					config.providers[i].allow_protected,
					config.providers[i].private_mask,
					PKCS11H_SLOTEVENT_METHOD_POLL,
					0,
					config.providers[i].cert_is_private
				)) != CKR_OK
			) {
				common_log (LOG_WARNING, "Cannot add PKCS#11 provider '%s': %ld-'%s'", config.providers[i].name, rv, pkcs11h_getMessage (rv));
			}
			else {
				have_at_least_one_provider = 1;
			}
		}
	}

	if (!have_at_least_one_provider) {
		common_log (LOG_FATAL, "Could not load any provider");
	}

#if defined(HAVE_W32_SYSTEM)
	command_handler (-1, &config);
#else
{
	pthread_t accept_thread = 0;
	int accept_socket = -1;

	if (run_mode == RUN_MODE_DAEMON || run_mode == RUN_MODE_MULTI_SERVER) {
		accept_socket = server_socket_create ();

		server_socket_accept (accept_socket, &accept_thread, &config);
	}

	if (run_mode == RUN_MODE_DAEMON) {
		/*
		 * Emulate assuan behavior
		 */
		int fds[2];
		char c;
		if (pipe (fds)==-1) {
			common_log (LOG_FATAL, "Could not create pipe");
		}
		close (0);
		dup2 (fds[0], 0);
		close (fds[0]);
		while (read (0, &c, 1) == -1 && errno == EINTR);
		close (fds[1]);
	}
	else {
		command_handler (-1, &config);
	}

	if (run_mode == RUN_MODE_DAEMON || run_mode == RUN_MODE_MULTI_SERVER) {
		server_socket_accept_terminate (accept_thread);
		server_socket_close (accept_socket);
	}
}
#endif

	pkcs11h_terminate ();

#if defined(USE_GNUTLS)
	gnutls_global_deinit ();
#endif

	dconfig_free (&config);

	if (log_file != NULL) {
		free (log_file);
		log_file = NULL;
	}

	if (config_file != NULL) {
		free (config_file);
		config_file = NULL;
	}

	if (default_config_file != NULL) {
		free (default_config_file);
		default_config_file = NULL;
	}

	if (home_dir != NULL) {
		free (home_dir);
		home_dir = NULL;
	}

	if (fp_log != NULL) {
		fclose (fp_log);
		fp_log = NULL;
	}

	return 0;
}