Beispiel #1
0
void protocol_start_session(DbXmlSessionData *session) {

  int r;
  DbXmlCredentials cred;
  DbXmlSessionOptions options;
  DbXmlSessionOptions *options_set;
  memset(&cred, 0, sizeof(DbXmlCredentials));
  memset(&options, 0, sizeof(DbXmlSessionOptions));

  if (initial_handshake(session) != 0)
    return;

  r = receive_credentials(session, &cred);

  if (r == 0)
    r = check_authentication(session, &cred);
  
  free_credentials(session, &cred);

  r = receive_session_options(session, &options);

  int init = -1;
  options_set = NULL;
  if (r == 0)
    init = r = initialize_session(session, &options, &options_set);

  session_response(session, r);

  if (r != 0)
    return;
  
  if (r == 0)
    r = send_session_options(session, options_set);

  free_session_options(session, &options);

  if (r == 0)
    protocol_request_response(session);
  
  if (init == 0)
    free_session(session);
  
}
Beispiel #2
0
/* This function is similar to pipe_connect but uses a socketpair and
   sets the I/O up to use sendmsg/recvmsg. */
static gpg_error_t
socketpair_connect (assuan_context_t ctx,
                    const char *name, const char **argv,
                    assuan_fd_t *fd_child_list,
                    void (*atfork) (void *opaque, int reserved),
                    void *atforkvalue)
{
  gpg_error_t err;
  int idx;
  int fds[2];
  char mypidstr[50];
  pid_t pid;
  int *child_fds = NULL;
  int child_fds_cnt = 0;
  struct at_socketpair_fork atp;
  int rc;

  TRACE_BEG3 (ctx, ASSUAN_LOG_CTX, "socketpair_connect", ctx,
	      "name=%s,atfork=%p,atforkvalue=%p", name ? name : "(null)",
	      atfork, atforkvalue);

  atp.user_atfork = atfork;
  atp.user_atforkvalue = atforkvalue;
  atp.parent_pid = getpid ();

  if (!ctx
      || (name && (!argv || !argv[0]))
      || (!name && !argv))
    return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE);

  if (! ctx->flags.no_fixsignals)
    fix_signals ();

  sprintf (mypidstr, "%lu", (unsigned long)getpid ());

  if (fd_child_list)
    while (fd_child_list[child_fds_cnt] != ASSUAN_INVALID_FD)
      child_fds_cnt++;
  child_fds = _assuan_malloc (ctx, (child_fds_cnt + 2) * sizeof (int));
  if (! child_fds)
    return TRACE_ERR (gpg_err_code_from_syserror ());
  child_fds[1] = ASSUAN_INVALID_FD;
  if (fd_child_list)
    memcpy (&child_fds[1], fd_child_list, (child_fds_cnt + 1) * sizeof (int));

  if (_assuan_socketpair (ctx, AF_LOCAL, SOCK_STREAM, 0, fds))
    {
      TRACE_LOG1 ("socketpair failed: %s", strerror (errno));
      _assuan_free (ctx, child_fds);
      return TRACE_ERR (GPG_ERR_ASS_GENERAL);
    }
  atp.peer_fd = fds[1];
  child_fds[0] = fds[1];

  rc = _assuan_spawn (ctx, &pid, name, argv, ASSUAN_INVALID_FD,
		      ASSUAN_INVALID_FD, child_fds, at_socketpair_fork_cb,
		      &atp, 0);
  if (rc < 0)
    {
      err = gpg_err_code_from_syserror ();
      _assuan_close (ctx, fds[0]);
      _assuan_close (ctx, fds[1]);
      _assuan_free (ctx, child_fds);
      return TRACE_ERR (err);
    }

  /* For W32, the user needs to know the server-local names of the
     inherited handles.  Return them here.  Note that the translation
     of the peer socketpair fd (fd_child_list[0]) must be done by the
     wrapper program based on the environment variable
     _assuan_connection_fd.  */
  if (fd_child_list)
    {
      for (idx = 0; fd_child_list[idx] != -1; idx++)
	/* We add 1 to skip over the socketpair end.  */
	fd_child_list[idx] = child_fds[idx + 1];
    }

  _assuan_free (ctx, child_fds);

  /* If this is the server child process, exit early.  */
  if (! name && (*argv)[0] == 's')
    {
      _assuan_close (ctx, fds[0]);
      return 0;
    }

  _assuan_close (ctx, fds[1]);

  ctx->engine.release = _assuan_client_release;
  ctx->finish_handler = _assuan_client_finish;
  ctx->max_accepts = 1;
  ctx->inbound.fd  = fds[0];
  ctx->outbound.fd = fds[0];
  _assuan_init_uds_io (ctx);

  err = initial_handshake (ctx);
  if (err)
    _assuan_reset (ctx);
  return err;
}
Beispiel #3
0
static gpg_error_t
pipe_connect (assuan_context_t ctx,
	      const char *name, const char **argv,
	      assuan_fd_t *fd_child_list,
	      void (*atfork) (void *opaque, int reserved),
	      void *atforkvalue, unsigned int flags)
{
  gpg_error_t rc;
  assuan_fd_t rp[2];
  assuan_fd_t wp[2];
  pid_t pid;
  int res;
  struct at_pipe_fork atp;
  unsigned int spawn_flags;

  atp.user_atfork = atfork;
  atp.user_atforkvalue = atforkvalue;
  atp.parent_pid = getpid ();

  if (!ctx || !name || !argv || !argv[0])
    return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE);

  if (! ctx->flags.no_fixsignals)
    fix_signals ();

  if (_assuan_pipe (ctx, rp, 1) < 0)
    return _assuan_error (ctx, gpg_err_code_from_syserror ());

  if (_assuan_pipe (ctx, wp, 0) < 0)
    {
      _assuan_close (ctx, rp[0]);
      _assuan_close_inheritable (ctx, rp[1]);
      return _assuan_error (ctx, gpg_err_code_from_syserror ());
    }

  spawn_flags = 0;
  if (flags & ASSUAN_PIPE_CONNECT_DETACHED)
    spawn_flags |= ASSUAN_SPAWN_DETACHED;

  /* FIXME: Use atfork handler that closes child fds on Unix.  */
  res = _assuan_spawn (ctx, &pid, name, argv, wp[0], rp[1],
		       fd_child_list, at_pipe_fork_cb, &atp, spawn_flags);
  if (res < 0)
    {
      rc = gpg_err_code_from_syserror ();
      _assuan_close (ctx, rp[0]);
      _assuan_close_inheritable (ctx, rp[1]);
      _assuan_close_inheritable (ctx, wp[0]);
      _assuan_close (ctx, wp[1]);
      return _assuan_error (ctx, rc);
    }

  /* Close the stdin/stdout child fds in the parent.  */
  _assuan_close_inheritable (ctx, rp[1]);
  _assuan_close_inheritable (ctx, wp[0]);

  ctx->engine.release = _assuan_client_release;
  ctx->engine.readfnc = _assuan_simple_read;
  ctx->engine.writefnc = _assuan_simple_write;
  ctx->engine.sendfd = NULL;
  ctx->engine.receivefd = NULL;
  ctx->finish_handler = _assuan_client_finish;
  ctx->max_accepts = 1;
  ctx->accept_handler = NULL;
  ctx->inbound.fd  = rp[0];  /* Our inbound is read end of read pipe. */
  ctx->outbound.fd = wp[1];  /* Our outbound is write end of write pipe. */
  ctx->pid = pid;

  rc = initial_handshake (ctx);
  if (rc)
    _assuan_reset (ctx);
  return rc;
}