Exemplo n.º 1
0
/* Write to the domain server.  */
static ssize_t
uds_writer (assuan_context_t ctx, const void *buf, size_t buflen)
{
#ifndef HAVE_W32_SYSTEM
  struct msghdr msg;
  struct iovec iovec;
  ssize_t len;

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

  msg.msg_name = NULL;
  msg.msg_namelen = 0;
  msg.msg_iovlen = 1;
  msg.msg_iov = &iovec;
  iovec.iov_base = (void*)buf;
  iovec.iov_len = buflen;

  len = _assuan_sendmsg (ctx, ctx->outbound.fd, &msg, 0);

  return len;
#else /*HAVE_W32_SYSTEM*/
  int res = sendto (HANDLE2SOCKET(ctx->outbound.fd), buf, buflen, 0,
		    (struct sockaddr *)&ctx->serveraddr,
		    sizeof (struct sockaddr_in));
  if (res < 0)
    gpg_err_set_errno ( _assuan_sock_wsa2errno (WSAGetLastError ()));
  return res;
#endif /*HAVE_W32_SYSTEM*/
}
Exemplo n.º 2
0
int
_assuan_sock_connect (assuan_fd_t sockfd, struct sockaddr *addr, int addrlen)
{
#ifdef HAVE_W32_SYSTEM
  if (addr->sa_family == AF_LOCAL || addr->sa_family == AF_UNIX)
    {
      struct sockaddr_in myaddr;
      struct sockaddr_un *unaddr;
      unsigned short port;
      char nonce[16];
      int ret;
      
      unaddr = (struct sockaddr_un *)addr;
      if (read_port_and_nonce (unaddr->sun_path, &port, nonce))
        return -1;
      
      myaddr.sin_family = AF_INET;
      myaddr.sin_port = htons (port); 
      myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
  
      /* Set return values.  */
      unaddr->sun_family = myaddr.sin_family;
      unaddr->sun_port = myaddr.sin_port;
      unaddr->sun_addr.s_addr = myaddr.sin_addr.s_addr;
  
      ret = connect (HANDLE2SOCKET(sockfd), 
                     (struct sockaddr *)&myaddr, sizeof myaddr);
      if (!ret)
        {
          /* Send the nonce. */
          ret = _assuan_io_write (sockfd, nonce, 16);
          if (ret >= 0 && ret != 16)
            {
              errno = EIO;
              ret = -1;
            }
        }
      return ret;
    }
  else
    {
      int res;
      res = connect (HANDLE2SOCKET (sockfd), addr, addrlen);
      if (res < 0)
	errno = _assuan_sock_wsa2errno (WSAGetLastError ());
      return res;
    }      
#else
  return connect (sockfd, addr, addrlen);
#endif
}
Exemplo n.º 3
0
/* Close the given file descriptor, created with _assuan_pipe or one
   of the socket functions.  Default implementation.  */
int
__assuan_close (assuan_context_t ctx, assuan_fd_t fd)
{
    int rc = closesocket (HANDLE2SOCKET(fd));
    if (rc)
        gpg_err_set_errno ( _assuan_sock_wsa2errno (WSAGetLastError ()) );
    if (rc && WSAGetLastError () == WSAENOTSOCK)
    {
        rc = CloseHandle (fd);
        if (rc)
            /* FIXME. */
            gpg_err_set_errno (EIO);
    }
    return rc;
}
Exemplo n.º 4
0
/* Return a new socket.  Note that under W32 we consider a socket the
   same as an System Handle; all functions using such a handle know
   about this dual use and act accordingly. */ 
assuan_fd_t
_assuan_sock_new (int domain, int type, int proto)
{
#ifdef HAVE_W32_SYSTEM
  assuan_fd_t res;
  if (domain == AF_UNIX || domain == AF_LOCAL)
    domain = AF_INET;
  res = SOCKET2HANDLE(socket (domain, type, proto));
  if (res == ASSUAN_INVALID_FD)
    errno = _assuan_sock_wsa2errno (WSAGetLastError ());
  return res;
#else
  return socket (domain, type, proto);
#endif
}
Exemplo n.º 5
0
int
_assuan_close (assuan_fd_t fd)
{
#ifdef HAVE_W32_SYSTEM
  int rc = closesocket (HANDLE2SOCKET(fd));
  if (rc)
    errno = _assuan_sock_wsa2errno (WSAGetLastError ());
  if (rc && WSAGetLastError () == WSAENOTSOCK)
    {
      rc = CloseHandle (fd);
      if (rc)
	/* FIXME. */
	errno = EIO;
    }
  return rc;
#else
  return close (fd);
#endif
}
Exemplo n.º 6
0
/* Close the given file descriptor, created with _assuan_pipe or one
   of the socket functions.  Default implementation.  */
int
__assuan_close (assuan_context_t ctx, assuan_fd_t fd)
{
  int rc = closesocket (HANDLE2SOCKET(fd));
  int err = WSAGetLastError ();

  /* Note that gpg_err_set_errno on Windows CE overwrites
     WSAGetLastError() (via SetLastError()).  */
  if (rc)
    gpg_err_set_errno (_assuan_sock_wsa2errno (err));
  if (rc && err == WSAENOTSOCK)
    {
      rc = CloseHandle (fd);
      if (rc)
        /* FIXME. */
        gpg_err_set_errno (EIO);
    }
  return rc;
}
Exemplo n.º 7
0
int
_assuan_sock_bind (assuan_context_t ctx, assuan_fd_t sockfd,
		   struct sockaddr *addr, int addrlen)
{
#ifdef HAVE_W32_SYSTEM
  if (addr->sa_family == AF_LOCAL || addr->sa_family == AF_UNIX)
    {
      struct sockaddr_in myaddr;
      struct sockaddr_un *unaddr;
      HANDLE filehd;
      int len = sizeof myaddr;
      int rc;
      char nonce[16];
      char tmpbuf[33+16];
      DWORD nwritten;

      if (get_nonce (nonce, 16))
        return -1;

      unaddr = (struct sockaddr_un *)addr;

      myaddr.sin_port = 0;
      myaddr.sin_family = AF_INET;
      myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);

      filehd = MyCreateFile (unaddr->sun_path, 
                             GENERIC_WRITE,
                             FILE_SHARE_READ,
                             NULL,
                             CREATE_NEW,
                             FILE_ATTRIBUTE_NORMAL,
                             NULL);
      if (filehd == INVALID_HANDLE_VALUE)
        {
          if (GetLastError () == ERROR_FILE_EXISTS)
            gpg_err_set_errno (WSAEADDRINUSE);
          return -1;
        }

      rc = bind (HANDLE2SOCKET (sockfd), (struct sockaddr *)&myaddr, len);
      if (!rc)
        rc = getsockname (HANDLE2SOCKET (sockfd), 
                          (struct sockaddr *)&myaddr, &len);
      if (rc)
        {
          int save_e = errno;
          CloseHandle (filehd);
          MyDeleteFile (unaddr->sun_path);
          gpg_err_set_errno (save_e);
          return rc;
        }
      snprintf (tmpbuf, sizeof tmpbuf, "%d\n", ntohs (myaddr.sin_port));
      len = strlen (tmpbuf);
      memcpy (tmpbuf+len, nonce,16);
      len += 16;
      
      if (!WriteFile (filehd, tmpbuf, len, &nwritten, NULL))
        {
          CloseHandle (filehd);
          MyDeleteFile (unaddr->sun_path);
          gpg_err_set_errno (EIO);
          return -1;
        }
      CloseHandle (filehd);
      return 0;
    }
  else
    {
      int res = bind (HANDLE2SOCKET(sockfd), addr, addrlen);
      if (res < 0)
	gpg_err_set_errno ( _assuan_sock_wsa2errno (WSAGetLastError ()));
      return res;
    }
#else
  return bind (sockfd, addr, addrlen);
#endif
}
Exemplo n.º 8
0
int
_assuan_sock_bind (assuan_fd_t sockfd, struct sockaddr *addr, int addrlen)
{
#ifdef HAVE_W32_SYSTEM
  if (addr->sa_family == AF_LOCAL || addr->sa_family == AF_UNIX)
    {
      struct sockaddr_in myaddr;
      struct sockaddr_un *unaddr;
      int filefd;
      FILE *fp;
      int len = sizeof myaddr;
      int rc;
      char nonce[16];

      if (get_nonce (nonce, 16))
        return -1;

      unaddr = (struct sockaddr_un *)addr;

      myaddr.sin_port = 0;
      myaddr.sin_family = AF_INET;
      myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);

      filefd = open (unaddr->sun_path, 
                     (O_WRONLY|O_CREAT|O_EXCL|O_BINARY), 
                     (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP));
      if (filefd == -1)
        {
          if (errno == EEXIST)
            errno = WSAEADDRINUSE;
          return -1;
        }
      fp = fdopen (filefd, "wb");
      if (!fp)
        { 
          int save_e = errno;
          close (filefd);
          errno = save_e;
          return -1;
        }

      rc = bind (HANDLE2SOCKET (sockfd), (struct sockaddr *)&myaddr, len);
      if (!rc)
        rc = getsockname (HANDLE2SOCKET (sockfd), 
                          (struct sockaddr *)&myaddr, &len);
      if (rc)
        {
          int save_e = errno;
          fclose (fp);
          remove (unaddr->sun_path);
          errno = save_e;
          return rc;
        }
      fprintf (fp, "%d\n", ntohs (myaddr.sin_port));
      fwrite (nonce, 16, 1, fp);
      fclose (fp);

      return 0;
    }
  else
    {
      int res = bind (HANDLE2SOCKET(sockfd), addr, addrlen);
      if (res < 0)
	errno = _assuan_sock_wsa2errno (WSAGetLastError ());
      return res;
    }
#else
  return bind (sockfd, addr, addrlen);
#endif
}
Exemplo n.º 9
0
/* Read from a unix domain socket using sendmsg.  */
static ssize_t
uds_reader (assuan_context_t ctx, void *buf, size_t buflen)
{
#ifndef HAVE_W32_SYSTEM
  int len = 0;
  /* This loop should be OK.  As FDs are followed by data, the
     readable status of the socket does not change and no new
     select/event-loop round is necessary.  */
  while (!len)  /* No data is buffered.  */
    {
      struct msghdr msg;
      struct iovec iovec;
#ifdef USE_DESCRIPTOR_PASSING
      union {
        struct cmsghdr cm;
        char control[CMSG_SPACE(sizeof (int))];
      } control_u;
      struct cmsghdr *cmptr;
#endif /*USE_DESCRIPTOR_PASSING*/

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

      msg.msg_name = NULL;
      msg.msg_namelen = 0;
      msg.msg_iov = &iovec;
      msg.msg_iovlen = 1;
      iovec.iov_base = buf;
      iovec.iov_len = buflen;
#ifdef USE_DESCRIPTOR_PASSING
      msg.msg_control = control_u.control;
      msg.msg_controllen = sizeof (control_u.control);
#endif

      len = _assuan_recvmsg (ctx, ctx->inbound.fd, &msg, 0);
      if (len < 0)
        return -1;
      if (len == 0)
	return 0;

#ifdef USE_DESCRIPTOR_PASSING
      cmptr = CMSG_FIRSTHDR (&msg);
      if (cmptr && cmptr->cmsg_len == CMSG_LEN (sizeof(int)))
        {
          if (cmptr->cmsg_level != SOL_SOCKET
              || cmptr->cmsg_type != SCM_RIGHTS)
            TRACE0 (ctx, ASSUAN_LOG_SYSIO, "uds_reader", ctx,
		    "unexpected ancillary data received");
          else
            {
              int fd;

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

              if (ctx->uds.pendingfdscount >= DIM (ctx->uds.pendingfds))
                {
		  TRACE1 (ctx, ASSUAN_LOG_SYSIO, "uds_reader", ctx,
			  "too many descriptors pending - "
			  "closing received descriptor %d", fd);
                  _assuan_close (ctx, fd);
                }
              else
                ctx->uds.pendingfds[ctx->uds.pendingfdscount++] = fd;
            }
	}
#endif /*USE_DESCRIPTOR_PASSING*/
    }

  return len;
#else /*HAVE_W32_SYSTEM*/
  int res = recvfrom (HANDLE2SOCKET(ctx->inbound.fd), buf, buflen, 0, NULL, NULL);
  if (res < 0)
    gpg_err_set_errno (_assuan_sock_wsa2errno (WSAGetLastError ()));
  return res;
#endif /*HAVE_W32_SYSTEM*/
}