static void server (void) { int rc; assuan_context_t ctx; log_info ("server started\n"); rc = assuan_new (&ctx); if (rc) log_fatal ("assuan_new failed: %s\n", gpg_strerror (rc)); rc = assuan_init_pipe_server (ctx, NULL); if (rc) log_fatal ("assuan_init_pipe_server failed: %s\n", gpg_strerror (rc)); rc = register_commands (ctx); if (rc) log_fatal ("register_commands failed: %s\n", gpg_strerror(rc)); assuan_set_log_stream (ctx, stderr); for (;;) { rc = assuan_accept (ctx); if (rc) { if (rc != -1) log_error ("assuan_accept failed: %s\n", gpg_strerror (rc)); break; } log_info ("client connected. Client's pid is %ld\n", (long)assuan_get_pid (ctx)); rc = assuan_process (ctx); if (rc) log_error ("assuan_process failed: %s\n", gpg_strerror (rc)); } assuan_release (ctx); }
/* Startup the server. CTRL must have been allocated by the caller and set to the default values. */ int gpg_server (ctrl_t ctrl) { int rc; int filedes[2]; assuan_context_t ctx = NULL; static const char hello[] = ("GNU Privacy Guard's OpenPGP server " VERSION " ready"); /* We use a pipe based server so that we can work from scripts. assuan_init_pipe_server will automagically detect when we are called with a socketpair and ignore FILEDES in this case. */ filedes[0] = assuan_fdopen (0); filedes[1] = assuan_fdopen (1); rc = assuan_new (&ctx); if (rc) { log_error ("failed to allocate the assuan context: %s\n", gpg_strerror (rc)); goto leave; } rc = assuan_init_pipe_server (ctx, filedes); if (rc) { log_error ("failed to initialize the server: %s\n", gpg_strerror (rc)); goto leave; } rc = register_commands (ctx); if (rc) { log_error ("failed to the register commands with Assuan: %s\n", gpg_strerror(rc)); goto leave; } assuan_set_pointer (ctx, ctrl); if (opt.verbose || opt.debug) { char *tmp = NULL; const char *s1 = getenv ("GPG_AGENT_INFO"); if (asprintf (&tmp, "Home: %s\n" "Config: %s\n" "AgentInfo: %s\n" "%s", opt.homedir, "fixme: need config filename", s1?s1:"[not set]", hello) > 0) { assuan_set_hello_line (ctx, tmp); free (tmp); } } else assuan_set_hello_line (ctx, hello); assuan_register_reset_notify (ctx, reset_notify); assuan_register_input_notify (ctx, input_notify); assuan_register_output_notify (ctx, output_notify); assuan_register_option_handler (ctx, option_handler); ctrl->server_local = xtrycalloc (1, sizeof *ctrl->server_local); if (!ctrl->server_local) { rc = gpg_error_from_syserror (); goto leave; } ctrl->server_local->assuan_ctx = ctx; ctrl->server_local->message_fd = GNUPG_INVALID_FD; if (DBG_ASSUAN) assuan_set_log_stream (ctx, log_get_stream ()); for (;;) { rc = assuan_accept (ctx); if (rc == -1) { rc = 0; break; } else if (rc) { log_info ("Assuan accept problem: %s\n", gpg_strerror (rc)); break; } rc = assuan_process (ctx); if (rc) { log_info ("Assuan processing failed: %s\n", gpg_strerror (rc)); continue; } } leave: xfree (ctrl->server_local); ctrl->server_local = NULL; assuan_release (ctx); return rc; }
int pinentry_loop2 (int infd, int outfd) { int rc; int filedes[2]; ASSUAN_CONTEXT ctx; /* Extra check to make sure we have dropped privs. */ #ifndef HAVE_DOSISH_SYSTEM if (getuid() != geteuid()) abort (); #endif /* For now we use a simple pipe based server so that we can work from scripts. We will later add options to run as a daemon and wait for requests on a Unix domain socket. */ filedes[0] = infd; filedes[1] = outfd; rc = assuan_init_pipe_server (&ctx, filedes); if (rc) { fprintf (stderr, "%s: failed to initialize the server: %s\n", this_pgmname, assuan_strerror(rc)); return -1; } rc = register_commands (ctx); if (rc) { fprintf (stderr, "%s: failed to the register commands with Assuan: %s\n", this_pgmname, assuan_strerror(rc)); return -1; } assuan_register_option_handler (ctx, option_handler); #if 0 assuan_set_log_stream (ctx, stderr); #endif for (;;) { rc = assuan_accept (ctx); if (rc == -1) break; else if (rc) { fprintf (stderr, "%s: Assuan accept problem: %s\n", this_pgmname, assuan_strerror (rc)); break; } rc = assuan_process (ctx); if (rc) { fprintf (stderr, "%s: Assuan processing failed: %s\n", this_pgmname, assuan_strerror (rc)); continue; } } assuan_deinit_server (ctx); return 0; }
/** Command handler (single-threaded). If fd == -1, this is a pipe server, otherwise fd is UNIX socket fd to which client connected. */ static void command_handler (const int fd, dconfig_data_t *config) { assuan_context_t ctx = NULL; cmd_data_t data; int ret; memset (&data, 0, sizeof (data)); data.config = config; if ((ret = assuan_new(&ctx)) != 0) { common_log (LOG_ERROR,"failed to create assuan context %s", gpg_strerror (ret)); goto cleanup; } if(fd < 0) { assuan_fd_t fds[2] = {assuan_fdopen(0), assuan_fdopen(1)}; ret = assuan_init_pipe_server (ctx, fds); } else { ret = assuan_init_socket_server (ctx, INT2FD(fd), ASSUAN_SOCKET_SERVER_ACCEPTED); } if (ret != 0) { common_log (LOG_ERROR,"failed to initialize server: %s", gpg_strerror (ret)); goto cleanup; } if(((ret = register_commands(ctx))) != 0) { common_log (LOG_ERROR,"failed to register assuan commands: %s", gpg_strerror (ret)); goto cleanup; } if (config->verbose) { assuan_set_log_stream (ctx, common_get_log_stream()); } assuan_set_pointer (ctx, &data); while (1) { if ((ret = assuan_accept (ctx)) == -1) { break; } if (ret != 0) { common_log (LOG_WARNING,"assuan_accept failed: %s", gpg_strerror(ret)); break; } if ((ret = assuan_process (ctx)) != 0) { common_log (LOG_WARNING,"assuan_process failed: %s", gpg_strerror(ret)); } } cleanup: if (ctx != NULL) { cmd_free_data (ctx); assuan_release (ctx); ctx = NULL; } }