Example #1
0
assuan_error_t
assuan_set_hello_line (assuan_context_t ctx, const char *line)
{
  if (!ctx)
    return _assuan_error (ASSUAN_Invalid_Value);
  if (!line)
    {
      xfree (ctx->hello_line);
      ctx->hello_line = NULL;
    }
  else
    {
      char *buf = xtrymalloc (3+strlen(line)+1);
      if (!buf)
        return _assuan_error (ASSUAN_Out_Of_Core);
      if (strchr (line, '\n'))
        strcpy (buf, line);
      else
        {
          strcpy (buf, "OK ");
          strcpy (buf+3, line);
        }
      xfree (ctx->hello_line);
      ctx->hello_line = buf;
    }
  return 0;
}
Example #2
0
gpg_error_t
assuan_send_data (assuan_context_t ctx, const void *buffer, size_t length)
{
  if (!ctx)
    return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE);
  if (!buffer && length > 1)
    return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE);

  if (!buffer)
    { /* flush what we have */
      _assuan_cookie_write_flush (ctx);
      if (ctx->outbound.data.error)
        return ctx->outbound.data.error;
      if (!ctx->is_server)
        return assuan_write_line (ctx, length == 1? "CAN":"END");
    }
  else
    {
      _assuan_cookie_write_data (ctx, buffer, length);
      if (ctx->outbound.data.error)
        return ctx->outbound.data.error;
    }

  return 0;
}
Example #3
0
assuan_error_t
assuan_send_data(assuan_context_t ctx, const void *buffer, size_t length)
{
    if(!ctx)
        return _assuan_error(ASSUAN_Invalid_Value);
    if(!buffer && length)
        return _assuan_error(ASSUAN_Invalid_Value);

    if(!buffer)
    {
        /* flush what we have */
        _assuan_cookie_write_flush(ctx);
        if(ctx->outbound.data.error)
            return ctx->outbound.data.error;
        if(!ctx->is_server)
            return assuan_write_line(ctx, "END");
    }
    else
    {
        _assuan_cookie_write_data(ctx, buffer, length);
        if(ctx->outbound.data.error)
            return ctx->outbound.data.error;
    }

    return 0;
}
Example #4
0
static gpg_error_t
uds_sendfd (assuan_context_t ctx, assuan_fd_t fd)
{
#ifdef USE_DESCRIPTOR_PASSING
  struct msghdr msg;
  struct iovec iovec;
  union {
    struct cmsghdr cm;
    char control[CMSG_SPACE(sizeof (int))];
  } control_u;
  struct cmsghdr *cmptr;
  int len;
  char buffer[80];

  /* We need to send some real data so that a read won't return 0
     which will be taken as an EOF.  It also helps with debugging. */
  snprintf (buffer, sizeof(buffer)-1, "# descriptor %d is in flight\n", fd);
  buffer[sizeof(buffer)-1] = 0;

  memset (&msg, 0, sizeof (msg));

  memset (&control_u, 0, sizeof (control_u));

  msg.msg_name = NULL;
  msg.msg_namelen = 0;
  msg.msg_iovlen = 1;
  msg.msg_iov = &iovec;
  iovec.iov_base = buffer;
  iovec.iov_len = strlen (buffer);

  msg.msg_control = control_u.control;
  msg.msg_controllen = sizeof (control_u.control);
  cmptr = CMSG_FIRSTHDR (&msg);
  cmptr->cmsg_len = CMSG_LEN(sizeof(int));
  cmptr->cmsg_level = SOL_SOCKET;
  cmptr->cmsg_type = SCM_RIGHTS;

  memcpy (CMSG_DATA (cmptr), &fd, sizeof (fd));

  len = _assuan_sendmsg (ctx, ctx->outbound.fd, &msg, 0);
  if (len < 0)
    {
      int saved_errno = errno;
      TRACE1 (ctx, ASSUAN_LOG_SYSIO, "uds_sendfd", ctx,
	      "uds_sendfd: %s", strerror (errno));
      errno = saved_errno;
      return _assuan_error (ctx, gpg_err_code_from_syserror ());
    }
  else
    return 0;
#else
  return _assuan_error (ctx, GPG_ERR_NOT_IMPLEMENTED);
#endif
}
Example #5
0
gpg_error_t
_assuan_write_line (assuan_context_t ctx, const char *prefix,
                    const char *line, size_t len)
{
  gpg_error_t rc = 0;
  size_t prefixlen = prefix? strlen (prefix):0;
  unsigned int monitor_result;

  /* Make sure that the line is short enough. */
  if (len + prefixlen + 2 > ASSUAN_LINELENGTH)
    {
      _assuan_log_control_channel (ctx, 1,
                                   "supplied line too long - truncated",
                                   NULL, 0, NULL, 0);
      if (prefixlen > 5)
        prefixlen = 5;
      if (len > ASSUAN_LINELENGTH - prefixlen - 2)
        len = ASSUAN_LINELENGTH - prefixlen - 2 - 1;
    }

  monitor_result = 0;
  if (ctx->io_monitor)
    monitor_result = ctx->io_monitor (ctx, ctx->io_monitor_data, 1, line, len);

  /* Fixme: we should do some kind of line buffering.  */
  if (!(monitor_result & ASSUAN_IO_MONITOR_NOLOG))
    _assuan_log_control_channel (ctx, 1, NULL,
                                 prefixlen? prefix:NULL, prefixlen,
                                 line, len);

  if (prefixlen && !(monitor_result & ASSUAN_IO_MONITOR_IGNORE))
    {
      rc = writen (ctx, prefix, prefixlen);
      if (rc)
	rc = _assuan_error (ctx, gpg_err_code_from_syserror ());
    }
  if (!rc && !(monitor_result & ASSUAN_IO_MONITOR_IGNORE))
    {
      rc = writen (ctx, line, len);
      if (rc)
	rc = _assuan_error (ctx, gpg_err_code_from_syserror ());
      if (!rc)
        {
          rc = writen (ctx, "\n", 1);
          if (rc)
	    rc = _assuan_error (ctx, gpg_err_code_from_syserror ());
        }
    }
  return rc;
}
Example #6
0
/* Return user credentials.  For getting the pid of the peer the
   assuan_get_pid is usually better suited. */
gpg_error_t
assuan_get_peercred (assuan_context_t ctx, assuan_peercred_t *peercred)
{
  TRACE (ctx, ASSUAN_LOG_CTX, "assuan_get_peercred", ctx);

  if (!ctx)
    return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE);
  if (!ctx->peercred_valid)
    return _assuan_error (ctx, GPG_ERR_ASS_GENERAL);

  *peercred = &ctx->peercred;

  return 0;
}
Example #7
0
/* Create a new context.  Note that the handlers are set up for a pipe
   server/client - this way we don't need extra dummy functions */
int
_assuan_new_context(assuan_context_t *r_ctx)
{
    static struct assuan_io io = { _assuan_simple_read,
               _assuan_simple_write,
               0, 0
    };

    assuan_context_t ctx;
    int rc;

    *r_ctx = NULL;
    ctx = xtrycalloc(1, sizeof * ctx);
    if(!ctx)
        return _assuan_error(ASSUAN_Out_Of_Core);
    ctx->input_fd = -1;
    ctx->output_fd = -1;

    ctx->inbound.fd = -1;
    ctx->outbound.fd = -1;
    ctx->io = &io;

    ctx->listen_fd = -1;
    /* Use the pipe server handler as a default.  */
    ctx->deinit_handler = deinit_pipe_server;
    ctx->accept_handler = accept_connection;
    ctx->finish_handler = finish_connection;

    rc = _assuan_register_std_commands(ctx);
    if(rc)
        xfree(ctx);
    else
        *r_ctx = ctx;
    return rc;
}
Example #8
0
static gpg_error_t
process_request (assuan_context_t ctx)
{
  gpg_error_t rc;

  if (ctx->in_inquire)
    return _assuan_error (ctx, GPG_ERR_ASS_NESTED_COMMANDS);

  do
    {
      rc = _assuan_read_line (ctx);
    }
  while (_assuan_error_is_eagain (ctx, rc));
  if (gpg_err_code (rc) == GPG_ERR_EOF)
    {
      ctx->process_complete = 1;
      return 0;
    }
  if (rc)
    return rc;
  if (*ctx->inbound.line == '#' || !ctx->inbound.linelen)
    return 0; /* comment line - ignore */

  ctx->in_command = 1;
  ctx->outbound.data.error = 0;
  ctx->outbound.data.linelen = 0;
  /* dispatch command and return reply */
  rc = dispatch_command (ctx, ctx->inbound.line, ctx->inbound.linelen);

  return assuan_process_done (ctx, rc);
}
Example #9
0
gpg_error_t
assuan_register_output_notify (assuan_context_t ctx, assuan_handler_t fnc)
{
  if (!ctx)
    return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE);
  ctx->output_notify_fnc = fnc;
  return 0;
}
Example #10
0
gpg_error_t
assuan_register_post_cmd_notify (assuan_context_t ctx,
                                 void (*fnc)(assuan_context_t, gpg_error_t))
{
  if (!ctx)
    return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE);
  ctx->post_cmd_notify_fnc = fnc;
  return 0;
}
Example #11
0
/* Close the fd descriptor set by the command INPUT FD=n.  We handle
   this fd inside assuan so that we can do some initial checks */
assuan_error_t
assuan_close_input_fd (assuan_context_t ctx)
{
  if (!ctx || ctx->input_fd == -1)
    return _assuan_error (ASSUAN_Invalid_Value);
  _assuan_close (ctx->input_fd);
  ctx->input_fd = -1;
  return 0;
}
Example #12
0
gpg_error_t
assuan_register_pre_cmd_notify (assuan_context_t ctx,
                                 gpg_error_t (*fnc)(assuan_context_t,
				   const char *cmd))
{
  if (!ctx)
    return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE);
  ctx->pre_cmd_notify_fnc = fnc;
  return 0;
}
Example #13
0
gpg_error_t
assuan_register_option_handler (assuan_context_t ctx,
				gpg_error_t (*fnc)(assuan_context_t,
						   const char*, const char*))
{
  if (!ctx)
    return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE);
  ctx->option_handler_fnc = fnc;
  return 0;
}
Example #14
0
/**
 * assuan_inquire_ext:
 * @ctx: An assuan context
 * @keyword: The keyword used for the inquire
 * @maxlen: If not 0, the size limit of the inquired data.
 * @cb: A callback handler which is invoked after the operation completed.
 * @cb_data: A user-provided value passed to the callback handler.
 * 
 * A Server may use this to Send an inquire.  r_buffer, r_length and
 * maxlen may all be NULL/0 to indicate that no real data is expected.
 * When this function returns, 
 *
 * Return value: 0 on success or an ASSUAN error code
 **/
gpg_error_t
assuan_inquire_ext (assuan_context_t ctx, const char *keyword, size_t maxlen,
		    gpg_error_t (*cb) (void *cb_data, gpg_error_t rc,
				       unsigned char *buf, size_t len),
		    void *cb_data)
{
  gpg_error_t rc;
  struct membuf *mb = NULL;
  char cmdbuf[LINELENGTH-10]; /* (10 = strlen ("INQUIRE ")+CR,LF) */

  if (!ctx || !keyword || (10 + strlen (keyword) >= sizeof (cmdbuf)))
    return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE);
  if (!ctx->is_server)
    return _assuan_error (ctx, GPG_ERR_ASS_NOT_A_SERVER);
  if (ctx->in_inquire)
    return _assuan_error (ctx, GPG_ERR_ASS_NESTED_COMMANDS);

  mb = malloc (sizeof (struct membuf));
  if (!mb)
    return _assuan_error (ctx, gpg_err_code_from_syserror ());
  init_membuf (ctx, mb, maxlen ? maxlen : 1024, maxlen);

  strcpy (stpcpy (cmdbuf, "INQUIRE "), keyword);
  rc = assuan_write_line (ctx, cmdbuf);
  if (rc)
    {
      free_membuf (ctx, mb); 
      free (mb);
      return rc;
    }

  ctx->in_inquire = 1;

  /* Set up the continuation.  */
  ctx->inquire_cb = cb;
  ctx->inquire_cb_data = cb_data;
  ctx->inquire_membuf = mb;

  return 0;
}
Example #15
0
/**
 * assuan_inquire_ext:
 * @ctx: An assuan context
 * @keyword: The keyword used for the inquire
 * @maxlen: If not 0, the size limit of the inquired data.
 * @cb: A callback handler which is invoked after the operation completed.
 * @cb_data: A user-provided value passed to the callback handler.
 * 
 * A Server may use this to Send an inquire.  r_buffer, r_length and
 * maxlen may all be NULL/0 to indicate that no real data is expected.
 * When this function returns, 
 *
 * Return value: 0 on success or an ASSUAN error code
 **/
assuan_error_t
assuan_inquire_ext (assuan_context_t ctx, const char *keyword, size_t maxlen,
		    int (*cb) (void *cb_data, int rc, unsigned char *buf,
			       size_t len),
		    void *cb_data)
{
  assuan_error_t rc;
  struct membuf *mb = NULL;
  char cmdbuf[LINELENGTH-10]; /* (10 = strlen ("INQUIRE ")+CR,LF) */

  if (!ctx || !keyword || (10 + strlen (keyword) >= sizeof (cmdbuf)))
    return _assuan_error (ASSUAN_Invalid_Value);
  if (!ctx->is_server)
    return _assuan_error (ASSUAN_Not_A_Server);
  if (ctx->in_inquire)
    return _assuan_error (ASSUAN_Nested_Commands);

  mb = malloc (sizeof (struct membuf));
  if (!mb)
    return _assuan_error (ASSUAN_Out_Of_Core);
  init_membuf (mb, maxlen ? maxlen : 1024, maxlen);

  strcpy (stpcpy (cmdbuf, "INQUIRE "), keyword);
  rc = assuan_write_line (ctx, cmdbuf);
  if (rc)
    {
      free_membuf (mb); 
      free (mb);
      return rc;
    }

  ctx->in_inquire = 1;

  /* Set up the continuation.  */
  ctx->inquire_cb = cb;
  ctx->inquire_cb_data = cb_data;
  ctx->inquire_membuf = mb;

  return 0;
}
Example #16
0
/* Read the next line from the client or server and return a pointer
   in *LINE to a buffer holding the line.  LINELEN is the length of
   *LINE.  The buffer is valid until the next read operation on it.
   The caller may modify the buffer.  The buffer is invalid (i.e. must
   not be used) if an error is returned.

   Returns 0 on success or an assuan error code.
   See also: assuan_pending_line().
*/
assuan_error_t
assuan_read_line(assuan_context_t ctx, char **line, size_t *linelen)
{
    assuan_error_t err;

    if(!ctx)
        return _assuan_error(ASSUAN_Invalid_Value);

    err = _assuan_read_line(ctx);
    *line = ctx->inbound.line;
    *linelen = ctx->inbound.linelen;
    return err;
}
Example #17
0
static gpg_error_t
uds_receivefd (assuan_context_t ctx, assuan_fd_t *fd)
{
#ifdef USE_DESCRIPTOR_PASSING
  int i;

  if (!ctx->uds.pendingfdscount)
    {
      TRACE0 (ctx, ASSUAN_LOG_SYSIO, "uds_receivefd", ctx,
	      "no pending file descriptors");
      return _assuan_error (ctx, GPG_ERR_ASS_GENERAL);
    }
  assert (ctx->uds.pendingfdscount <= DIM(ctx->uds.pendingfds));

  *fd = ctx->uds.pendingfds[0];
  for (i=1; i < ctx->uds.pendingfdscount; i++)
    ctx->uds.pendingfds[i-1] = ctx->uds.pendingfds[i];
  ctx->uds.pendingfdscount--;

  return 0;
#else
  return _assuan_error (ctx, GPG_ERR_NOT_IMPLEMENTED);
#endif
}
Example #18
0
/* Set the text used for the next OK reponse.  This string is
   automatically reset to NULL after the next command. */
gpg_error_t
assuan_set_okay_line (assuan_context_t ctx, const char *line)
{
  if (!ctx)
    return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE);
  if (!line)
    {
      _assuan_free (ctx, ctx->okay_line);
      ctx->okay_line = NULL;
    }
  else
    {
      /* FIXME: we need to use gcry_is_secure() to test whether
         we should allocate the entire line in secure memory */
      char *buf = _assuan_malloc (ctx, 3 + strlen(line) + 1);
      if (!buf)
        return _assuan_error (ctx, gpg_err_code_from_syserror ());
      strcpy (buf, "OK ");
      strcpy (buf+3, line);
      _assuan_free (ctx, ctx->okay_line);
      ctx->okay_line = buf;
    }
  return 0;
}
Example #19
0
static int
accept_connection (assuan_context_t ctx)
{
  assuan_fd_t fd;
  struct sockaddr_un clnt_addr;
  socklen_t len = sizeof clnt_addr;

  fd = SOCKET2HANDLE(accept (HANDLE2SOCKET(ctx->listen_fd), 
                             (struct sockaddr*)&clnt_addr, &len ));
  if (fd == ASSUAN_INVALID_FD)
    {
      ctx->os_errno = errno;
      return _assuan_error (ASSUAN_Accept_Failed);
    }
  if (_assuan_sock_check_nonce (fd, &ctx->listen_nonce))
    {
      _assuan_close (fd);
      ctx->os_errno = EACCES;
      return _assuan_error (ASSUAN_Accept_Failed);
    }

  ctx->connected_fd = fd;
  return accept_connection_bottom (ctx);
}
Example #20
0
/* 
   Flag bits: 0 - use sendmsg/recvmsg to allow descriptor passing
              1 - FD has already been accepted.
*/
int
assuan_init_socket_server_ext (assuan_context_t *r_ctx, assuan_fd_t fd,
                               unsigned int flags)
{
  assuan_context_t ctx;
  int rc;

  *r_ctx = NULL;
  ctx = xtrycalloc (1, sizeof *ctx);
  if (!ctx)
    return _assuan_error (ASSUAN_Out_Of_Core);
  ctx->is_server = 1;
  if ((flags & 2))
    ctx->pipe_mode = 1; /* We want a second accept to indicate EOF. */
  ctx->input_fd = ASSUAN_INVALID_FD;
  ctx->output_fd = ASSUAN_INVALID_FD;

  ctx->inbound.fd = ASSUAN_INVALID_FD;
  ctx->outbound.fd = ASSUAN_INVALID_FD;

  if ((flags & 2))
    {
      ctx->listen_fd = ASSUAN_INVALID_FD;
      ctx->connected_fd = fd;
    }
  else
    {
      ctx->listen_fd = fd;
      ctx->connected_fd = ASSUAN_INVALID_FD;
    }
  ctx->deinit_handler = (flags & 1)? _assuan_uds_deinit:deinit_socket_server;
  ctx->accept_handler = ((flags & 2)
                         ? accept_connection_bottom 
                         : accept_connection);
  ctx->finish_handler = finish_connection;

  ctx->io = &io;
  if ((flags & 1))
    _assuan_init_uds_io (ctx);

  rc = _assuan_register_std_commands (ctx);
  if (rc)
    xfree (ctx);
  else
    *r_ctx = ctx;
  return rc;
}
Example #21
0
/* Write out any buffered data
   This function is used for GNU's custom streams */
int
_assuan_cookie_write_flush(void *cookie)
{
    assuan_context_t ctx = cookie;
    char *line;
    size_t linelen;
    unsigned int monitor_result;

    if(ctx->outbound.data.error)
        return 0;

    line = ctx->outbound.data.line;
    linelen = ctx->outbound.data.linelen;
    line += linelen;

    monitor_result = (ctx->io_monitor
                      ? ctx->io_monitor(ctx, 1,
                                        ctx->outbound.data.line, linelen)
                      : 0);

    if(linelen)
    {
        if(ctx->log_fp && !(monitor_result & 1))
        {
            fprintf(ctx->log_fp, "%s[%u.%d] DBG: -> ",
                    assuan_get_assuan_log_prefix(),
                    (unsigned int)getpid(), ctx->inbound.fd);
            if(ctx->confidential)
                fputs("[Confidential data not shown]", ctx->log_fp);
            else
                _assuan_log_print_buffer(ctx->log_fp,
                                         ctx->outbound.data.line, linelen);
            putc('\n', ctx->log_fp);
        }
        *line++ = '\n';
        linelen++;
        if(!(monitor_result & 2)
                && writen(ctx, ctx->outbound.data.line, linelen))
        {
            ctx->outbound.data.error = _assuan_error(ASSUAN_Write_Error);
            return 0;
        }
        ctx->outbound.data.linelen = 0;
    }
    return 0;
}
Example #22
0
/**
 * assuan_accept:
 * @ctx: context
 * 
 * Cancel any existing connection and wait for a connection from a
 * client.  The initial handshake is performed which may include an
 * initial authentication or encryption negotiation.
 * 
 * Return value: 0 on success or an error if the connection could for
 * some reason not be established.
 **/
assuan_error_t
assuan_accept (assuan_context_t ctx)
{
  int rc;
  const char *p, *pend;

  if (!ctx)
    return _assuan_error (ASSUAN_Invalid_Value);

  if (ctx->pipe_mode > 1)
    return -1; /* second invocation for pipemode -> terminate */
  ctx->finish_handler (ctx);

  rc = ctx->accept_handler (ctx);
  if (rc)
    return rc;

  /* Send the hello. */
  p = ctx->hello_line;
  if (p && (pend = strchr (p, '\n')))
    { /* This is a multi line hello.  Send all but the last line as
         comments. */
      do
        {
          rc = _assuan_write_line (ctx, "# ", p, pend - p);
          if (rc)
            return rc;
          p = pend + 1;
          pend = strchr (p, '\n');
        }
      while (pend);
      rc = _assuan_write_line (ctx, "OK ", p, strlen (p));
    }
  else if (p)
    rc = assuan_write_line (ctx, p);
  else
    rc = assuan_write_line (ctx, "OK Pleased to meet you");
  if (rc)
    return rc;
  
  if (ctx->pipe_mode)
    ctx->pipe_mode = 2;
  
  return 0;
}
Example #23
0
gpg_error_t
assuan_sendfd (assuan_context_t ctx, assuan_fd_t fd)
{
  /* It is explicitly allowed to use (NULL, -1) as a runtime test to
     check whether descriptor passing is available. */
  if (!ctx && fd == ASSUAN_INVALID_FD)
#ifdef USE_DESCRIPTOR_PASSING
    return 0;
#else
  return _assuan_error (ctx, GPG_ERR_NOT_IMPLEMENTED);
#endif

  if (! ctx->engine.sendfd)
    return set_error (ctx, GPG_ERR_NOT_IMPLEMENTED,
		      "server does not support sending and receiving "
		      "of file descriptors");
  return ctx->engine.sendfd (ctx, fd);
}
Example #24
0
assuan_error_t
assuan_sendfd(assuan_context_t ctx, int fd)
{
    /* It is explicitly allowed to use (NULL, -1) as a runtime test to
       check whether descriptor passing is available. */
    if(!ctx && fd == -1)
#ifdef USE_DESCRIPTOR_PASSING
        return 0;
#else
        return _assuan_error(ASSUAN_Not_Implemented);
#endif

    if(! ctx->io->sendfd)
        return set_error(ctx, Not_Implemented,
                         "server does not support sending and receiving "
                         "of file descriptors");
    return ctx->io->sendfd(ctx, fd);
}
Example #25
0
/* Read the next line from the client or server and return a pointer
   in *LINE to a buffer holding the line.  LINELEN is the length of
   *LINE.  The buffer is valid until the next read operation on it.
   The caller may modify the buffer.  The buffer is invalid (i.e. must
   not be used) if an error is returned.

   Returns 0 on success or an assuan error code.
   See also: assuan_pending_line().
*/
gpg_error_t
assuan_read_line (assuan_context_t ctx, char **line, size_t *linelen)
{
  gpg_error_t err;

  if (!ctx)
    return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE);

  do
    {
      err = _assuan_read_line (ctx);
    }
  while (_assuan_error_is_eagain (ctx, err));

  *line = ctx->inbound.line;
  *linelen = ctx->inbound.linelen;

  return err;
}
Example #26
0
static gpg_error_t
_assuan_connect_finalize (assuan_context_t ctx, assuan_fd_t fd,
                          unsigned int flags)
{
  gpg_error_t err;

  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->inbound.fd = fd;
  ctx->outbound.fd = fd;
  ctx->max_accepts = -1;

  if (flags & ASSUAN_SOCKET_CONNECT_FDPASSING)
    _assuan_init_uds_io (ctx);

  /* initial handshake */
  {
    assuan_response_t response;
    int off;

    err = _assuan_read_from_server (ctx, &response, &off, 0);
    if (err)
      TRACE1 (ctx, ASSUAN_LOG_SYSIO, "assuan_socket_connect", ctx,
	      "can't connect to server: %s\n", gpg_strerror (err));
    else if (response != ASSUAN_RESPONSE_OK)
      {
	char *sname = _assuan_encode_c_string (ctx, ctx->inbound.line);
	if (sname)
	  {
	    TRACE1 (ctx, ASSUAN_LOG_SYSIO, "assuan_socket_connect", ctx,
		    "can't connect to server: %s", sname);
	    _assuan_free (ctx, sname);
	  }
	err = _assuan_error (ctx, GPG_ERR_ASS_CONNECT_FAILED);
      }
  }

  return err;
}
Example #27
0
gpg_error_t
assuan_write_status (assuan_context_t ctx,
                     const char *keyword, const char *text)
{
  char buffer[256];
  char *helpbuf;
  size_t n;
  gpg_error_t ae;

  if ( !ctx || !keyword)
    return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE);
  if (!text)
    text = "";

  n = 2 + strlen (keyword) + 1 + strlen (text) + 1;
  if (n < sizeof (buffer))
    {
      strcpy (buffer, "S ");
      strcat (buffer, keyword);
      if (*text)
        {
          strcat (buffer, " ");
          strcat (buffer, text);
        }
      ae = assuan_write_line (ctx, buffer);
    }
  else if ( (helpbuf = _assuan_malloc (ctx, n)) )
    {
      strcpy (helpbuf, "S ");
      strcat (helpbuf, keyword);
      if (*text)
        {
          strcat (helpbuf, " ");
          strcat (helpbuf, text);
        }
      ae = assuan_write_line (ctx, helpbuf);
      _assuan_free (ctx, helpbuf);
    }
  else
    ae = 0;
  return ae;
}
Example #28
0
/* Helper for pipe_connect. */
static gpg_error_t
initial_handshake (assuan_context_t ctx)
{
  assuan_response_t response;
  int off;
  gpg_error_t err;

  err = _assuan_read_from_server (ctx, &response, &off, 0);
  if (err)
    TRACE1 (ctx, ASSUAN_LOG_SYSIO, "initial_handshake", ctx,
	    "can't connect server: %s", gpg_strerror (err));
  else if (response != ASSUAN_RESPONSE_OK)
    {
      TRACE1 (ctx, ASSUAN_LOG_SYSIO, "initial_handshake", ctx,
	      "can't connect server: `%s'", ctx->inbound.line);
      err = _assuan_error (ctx, GPG_ERR_ASS_CONNECT_FAILED);
    }

  return err;
}
Example #29
0
gpg_error_t
assuan_write_line (assuan_context_t ctx, const char *line)
{
  size_t len;
  const char *str;

  if (! ctx)
    return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE);

  /* Make sure that we never take a LF from the user - this might
     violate the protocol. */
  str = strchr (line, '\n');
  len = str ? (str - line) : strlen (line);

  if (str)
    _assuan_log_control_channel (ctx, 1,
                                 "supplied line with LF - truncated",
                                 NULL, 0, NULL, 0);

  return _assuan_write_line (ctx, NULL, line, len);
}
Example #30
0
assuan_error_t
assuan_write_line(assuan_context_t ctx, const char *line)
{
    size_t len;
    const char *s;

    if(!ctx)
        return _assuan_error(ASSUAN_Invalid_Value);

    /* Make sure that we never take a LF from the user - this might
       violate the protocol. */
    s = strchr(line, '\n');
    len = s ? (s - line) : strlen(line);

    if(ctx->log_fp && s)
        fprintf(ctx->log_fp, "%s[%u.%d] DBG: -> "
                "[supplied line contained a LF - truncated]\n",
                assuan_get_assuan_log_prefix(),
                (unsigned int)getpid(), ctx->inbound.fd);

    return _assuan_write_line(ctx, NULL, line, len);
}