Ejemplo n.º 1
0
ssize_t
system_writev(gnutls_transport_ptr_t ptr, const giovec_t * iovec,
	      int iovec_cnt)
{
	return writev(GNUTLS_POINTER_TO_INT(ptr), (struct iovec *) iovec,
		      iovec_cnt);
}
Ejemplo n.º 2
0
/* Wait for data to be received within a timeout period in milliseconds.
 * To catch a termination it will also try to receive 0 bytes from the
 * socket if select reports to proceed.
 *
 * Returns -1 on error, 0 on timeout, positive value if data are available for reading.
 */
int system_recv_timeout(gnutls_transport_ptr_t ptr, unsigned int ms)
{
fd_set rfds;
struct timeval tv;
int ret;
int fd = GNUTLS_POINTER_TO_INT(ptr);

  FD_ZERO(&rfds);
  FD_SET(fd, &rfds);
  
  tv.tv_sec = 0;
  tv.tv_usec = ms * 1000;
  
  while(tv.tv_usec >= 1000000)
    {
      tv.tv_usec -= 1000000;
      tv.tv_sec++;
    }
  
  ret = select(fd+1, &rfds, NULL, NULL, &tv);
  if (ret <= 0)
    return ret;

  return ret;
}
Ejemplo n.º 3
0
static ssize_t
_system_writev(gnutls_transport_ptr_t ptr, const giovec_t * iovec,
	      int iovec_cnt, int flags)
{
	struct msghdr hdr;

	memset(&hdr, 0, sizeof(hdr));
	hdr.msg_iov = (struct iovec *)iovec;
	hdr.msg_iovlen = iovec_cnt;

	return sendmsg(GNUTLS_POINTER_TO_INT(ptr), &hdr, flags);
}
Ejemplo n.º 4
0
ssize_t
system_writev_nosignal(gnutls_transport_ptr_t ptr, const giovec_t * iovec,
	      int iovec_cnt)
{
	struct msghdr hdr;

	memset(&hdr, 0, sizeof(hdr));
	hdr.msg_iov = (struct iovec *)iovec;
	hdr.msg_iovlen = iovec_cnt;

	return sendmsg(GNUTLS_POINTER_TO_INT(ptr), &hdr, MSG_NOSIGNAL);
}
Ejemplo n.º 5
0
/* Wait for data to be received within a timeout period in milliseconds.
 * If data_size > 0 it will return the specified amount of data in
 * peek mode.
 *
 * Returns -1 on error, 0 on timeout.
 */
int system_recv_timeout(gnutls_transport_ptr_t ptr, unsigned int ms)
{
fd_set rfds;
struct timeval tv;
int ret, ret2;

  FD_ZERO(&rfds);
  FD_SET(GNUTLS_POINTER_TO_INT(ptr), &rfds);
  
  tv.tv_sec = 0;
  tv.tv_usec = ms * 1000;
  
  ret = select(GNUTLS_POINTER_TO_INT(ptr)+1, &rfds, NULL, NULL, &tv);
  if (ret <= 0)
    return ret;

  
  ret2 = recv(GNUTLS_POINTER_TO_INT(ptr), NULL, 0, MSG_PEEK);
  if (ret2 == -1)
    return ret2;
      
  return ret;
}
Ejemplo n.º 6
0
/**
 * gnutls_system_recv_timeout:
 * @ptr: A gnutls_transport_ptr_t pointer
 * @ms: The number of milliseconds to wait.
 *
 * Wait for data to be received from the provided socket (@ptr) within a
 * timeout period in milliseconds, using select() on the provided @ptr.
 *
 * This function is provided as a helper for constructing custom
 * callbacks for gnutls_transport_set_pull_timeout_function(),
 * which can be used if you rely on socket file descriptors.
 *
 * Returns -1 on error, 0 on timeout, positive value if data are available for reading.
 *
 * Since: 3.4.0
 **/
int gnutls_system_recv_timeout(gnutls_transport_ptr_t ptr, unsigned int ms)
{
	int ret;
	int fd = GNUTLS_POINTER_TO_INT(ptr);
#ifndef _WIN32
	int timeo;
	struct pollfd pfd;

	pfd.fd = fd;
	pfd.events = POLLIN;
	pfd.revents = 0;

	if (ms == GNUTLS_INDEFINITE_TIMEOUT)
		timeo = -1;
	else
		timeo = ms;
	do {
		ret = poll(&pfd, 1, timeo);
	} while(ret == -1 && errno == EINTR);
#else
	fd_set rfds;
	struct timeval _tv, *tv = NULL;

	FD_ZERO(&rfds);
	FD_SET(fd, &rfds);

	if (ms != GNUTLS_INDEFINITE_TIMEOUT) {
		_tv.tv_sec = ms/1000;
		_tv.tv_usec = (ms % 1000) * 1000;
		tv = &_tv;
	}

	ret = select(fd + 1, &rfds, NULL, NULL, tv);
#endif
	if (ret <= 0)
		return ret;

	return ret;
}
Ejemplo n.º 7
0
void
BIO_get_fd (gnutls_session_t gnutls_state, int *fd)
{
  gnutls_transport_ptr_t tmp = gnutls_transport_get_ptr (gnutls_state);
  *fd = GNUTLS_POINTER_TO_INT (tmp);
}
Ejemplo n.º 8
0
ssize_t
system_write (gnutls_transport_ptr ptr, const void *data, size_t data_size)
{
  return send (GNUTLS_POINTER_TO_INT (ptr), data, data_size, 0);
}
Ejemplo n.º 9
0
ssize_t
system_read (gnutls_transport_ptr_t ptr, void *data, size_t data_size)
{
  return recv (GNUTLS_POINTER_TO_INT (ptr), data, data_size, 0);
}
Ejemplo n.º 10
0
void
BIO_get_fd (gnutls_session_t gnutls_state, int *fd)
{
  *fd = GNUTLS_POINTER_TO_INT (gnutls_transport_get_ptr (gnutls_state));
}
Ejemplo n.º 11
0
/* This function is like write. But it does not return -1 on error.
 * It does return gnutls_errno instead.
 *
 * In case of E_AGAIN and E_INTERRUPTED errors, you must call gnutls_write_flush(),
 * until it returns ok (0).
 *
 * We need to push exactly the data in n, since we cannot send less
 * data. In TLS the peer must receive the whole packet in order
 * to decrypt and verify the integrity.
 *
 */
ssize_t
_gnutls_io_write_buffered (gnutls_session_t session,
                           const void *iptr, size_t n)
{
    size_t left;
    unsigned j, x, sum = 0;
    ssize_t retval, i;
    const opaque *ptr;
    int ret;
    gnutls_transport_ptr_t fd = session->internals.transport_send_ptr;

    /* to know where the procedure was interrupted.
     */
    session->internals.direction = 1;

    ptr = iptr;

    /* In case the previous write was interrupted, check if the
     * iptr != NULL and we have data in the buffer.
     * If this is true then return an error.
     */
    if (session->internals.record_send_buffer.length > 0 && iptr != NULL)
    {
        gnutls_assert ();
        return GNUTLS_E_INVALID_REQUEST;
    }

    /* If data in the buffer exist
     */
    if (iptr == NULL)
    {
        /* checking is handled above */
        ret =
            _gnutls_buffer_get (&session->internals.record_send_buffer, &ptr, &n);
        if (ret < 0)
        {
            gnutls_assert ();
            return ret;
        }

        _gnutls_write_log
        ("WRITE: Restoring old write. (%d bytes to send)\n", n);
    }

    _gnutls_write_log ("WRITE: Will write %d bytes to %d.\n", n, fd);

    i = 0;
    left = n;
    while (left > 0)
    {

        if (session->internals._gnutls_push_func == NULL)
            i = send (GNUTLS_POINTER_TO_INT(fd), &ptr[n - left], left, 0);
        else
            i = session->internals._gnutls_push_func (fd, &ptr[n - left], left);

        if (i == -1)
        {
            if (errno == EAGAIN || errno == EINTR)
            {
                session->internals.record_send_buffer_prev_size += n - left;

                retval =
                    _gnutls_buffer_insert (&session->internals.
                                           record_send_buffer,
                                           &ptr[n - left], left);
                if (retval < 0)
                {
                    gnutls_assert ();
                    return retval;
                }

                _gnutls_write_log
                ("WRITE: Interrupted. Stored %d bytes to buffer. Already sent %d bytes.\n",
                 left, n - left);

                retval = RET (errno);

                return retval;
            }
            else
            {
                gnutls_assert ();
                return GNUTLS_E_PUSH_ERROR;
            }
        }
        left -= i;


        if (_gnutls_log_level >= 7)
        {
            char line[128];
            char tmp[16];


            _gnutls_write_log
            ("WRITE: wrote %d bytes to %d. Left %d bytes. Total %d bytes.\n",
             i, fd, left, n);
            for (x = 0; x < (unsigned) ((i) / 16) + 1; x++)
            {
                line[0] = 0;

                if (sum > n - left)
                    break;

                sprintf (tmp, "%.4x - ", x);
                _gnutls_str_cat (line, sizeof (line), tmp);

                for (j = 0; j < 16; j++)
                {
                    if (sum < n - left)
                    {
                        sprintf (tmp, "%.2x ", ((unsigned char *) ptr)[sum++]);
                        _gnutls_str_cat (line, sizeof (line), tmp);
                    }
                    else
                        break;
                }
                _gnutls_write_log ("%s\n", line);
            }
        }
    }

    retval = n + session->internals.record_send_buffer_prev_size;

    session->internals.record_send_buffer.length = 0;
    session->internals.record_send_buffer_prev_size = 0;

    return retval;

}
Ejemplo n.º 12
0
/* This function is like read. But it does not return -1 on error.
 * It does return gnutls_errno instead.
 *
 * Flags are only used if the default recv() function is being used.
 */
static ssize_t
_gnutls_read (gnutls_session_t session, void *iptr,
              size_t sizeOfPtr, int flags)
{
    size_t left;
    ssize_t i = 0;
    char *ptr = iptr;
    unsigned j, x, sum = 0;
    gnutls_transport_ptr_t fd = session->internals.transport_recv_ptr;

    session->internals.direction = 0;

    left = sizeOfPtr;
    while (left > 0)
    {

        if (session->internals._gnutls_pull_func == NULL)
            i = recv (GNUTLS_POINTER_TO_INT(fd), &ptr[sizeOfPtr - left],
                      left, flags);
        else
            i = session->internals._gnutls_pull_func (fd,
                    &ptr[sizeOfPtr -
                         left], left);

        if (i < 0)
        {
            _gnutls_read_log ("READ: %d returned from %d, errno=%d\n", i,
                              fd, errno);

            if (errno == EAGAIN || errno == EINTR)
            {
                if (sizeOfPtr - left > 0)
                {

                    _gnutls_read_log ("READ: returning %d bytes from %d\n",
                                      sizeOfPtr - left, fd);

                    goto finish;
                }
                gnutls_assert ();

                return RET (errno);
            }
            else
            {
                gnutls_assert ();
                return GNUTLS_E_PULL_ERROR;
            }
        }
        else
        {

            _gnutls_read_log ("READ: Got %d bytes from %d\n", i, fd);

            if (i == 0)
                break;		/* EOF */
        }

        left -= i;

    }

finish:

    if (_gnutls_log_level >= 7)
    {
        char line[128];
        char tmp[16];


        _gnutls_read_log ("READ: read %d bytes from %d\n",
                          (sizeOfPtr - left), fd);

        for (x = 0; x < ((sizeOfPtr - left) / 16) + 1; x++)
        {
            line[0] = 0;

            sprintf (tmp, "%.4x - ", x);
            _gnutls_str_cat (line, sizeof (line), tmp);

            for (j = 0; j < 16; j++)
            {
                if (sum < (sizeOfPtr - left))
                {
                    sprintf (tmp, "%.2x ", ((unsigned char *) ptr)[sum++]);
                    _gnutls_str_cat (line, sizeof (line), tmp);
                }
            }
            _gnutls_read_log ("%s\n", line);
        }
    }

    return (sizeOfPtr - left);
}
Ejemplo n.º 13
0
/* This function is like write. But it does not return -1 on error.
 * It does return MHD_gnutls_errno instead.
 *
 * In case of E_AGAIN and E_INTERRUPTED errors, you must call MHD_gnutls_write_flush(),
 * until it returns ok (0).
 *
 * We need to push exactly the data in n, since we cannot send less
 * data. In TLS the peer must receive the whole packet in order
 * to decrypt and verify the integrity.
 *
 */
ssize_t
MHD_gtls_io_write_buffered (MHD_gtls_session_t session,
                            const void *iptr, size_t n)
{
  size_t left;
  unsigned j, x, sum = 0;
  ssize_t retval, i;
  const opaque *ptr;
  int ret;
  MHD_gnutls_transport_ptr_t fd = session->internals.transport_send_ptr;

  /* to know where the procedure was interrupted.
   */
  session->internals.direction = 1;

  ptr = iptr;

  /* In case the previous write was interrupted, check if the
   * iptr != NULL and we have data in the buffer.
   * If this is true then return an error.
   */
  if (session->internals.record_send_buffer.length > 0 && iptr != NULL)
    {
      MHD_gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  /* If data in the buffer exist
   */
  if (iptr == NULL)
    {
      /* checking is handled above */
      ret =
        MHD__gnutls_buffer_get (&session->internals.record_send_buffer, &ptr,
                                &n);
      if (ret < 0)
        {
          MHD_gnutls_assert ();
          return ret;
        }

      MHD__gnutls_write_log
        ("WRITE: Restoring old write. (%d bytes to send)\n", n);
    }

  MHD__gnutls_write_log ("WRITE: Will write %d bytes to %d.\n", n, fd);

  i = 0;
  left = n;
  while (left > 0)
    {

      session->internals.errnum = 0;

      if (session->internals.MHD__gnutls_push_func == NULL)
        {
          i = send (GNUTLS_POINTER_TO_INT (fd), &ptr[n - left], left, 0);
#if HAVE_WINSOCK
          if (i < 0)
            {
              int tmperr = WSAGetLastError ();
              switch (tmperr)
                {
                case WSAEWOULDBLOCK:
                  session->internals.errnum = EAGAIN;
                  break;

                case WSAEINTR:
                  session->internals.errnum = EINTR;
                  break;

                default:
                  session->internals.errnum = EIO;
                  break;
                }
              WSASetLastError (tmperr);
            }
#endif
        }
      else
	i = session->internals.MHD__gnutls_push_func (fd, &ptr[n - left], left);
      if (i == -1)
        {
          int err = session->internals.errnum ? session->internals.errnum
            : errno;

          if ( (err == EAGAIN) || (err == EINTR) )
            {
              session->internals.record_send_buffer_prev_size += n - left;

              retval =
                MHD__gnutls_buffer_insert (&session->
                                           internals.record_send_buffer,
                                           &ptr[n - left], left);
              if (retval < 0)
                {
                  MHD_gnutls_assert ();
                  return retval;
                }
              if (err == EAGAIN)
                return GNUTLS_E_AGAIN;
              return GNUTLS_E_INTERRUPTED;
            }
          else
            {
              MHD_gnutls_assert ();
              return GNUTLS_E_PUSH_ERROR;
            }
        }
      left -= i;

      if (MHD__gnutls_log_level >= 7)
        {
          char line[128];
          char tmp[16];

          MHD__gnutls_write_log
            ("WRITE: wrote %d bytes to %d. Left %d bytes. Total %d bytes.\n",
             i, fd, left, n);
          for (x = 0; x < (unsigned) ((i) / 16) + 1; x++)
            {
              line[0] = 0;

              if (sum > n - left)
                break;

              sprintf (tmp, "%.4x - ", x);
              MHD_gtls_str_cat (line, sizeof (line), tmp);

              for (j = 0; j < 16; j++)
                {
                  if (sum < n - left)
                    {
                      sprintf (tmp, "%.2x ", ((unsigned char *) ptr)[sum++]);
                      MHD_gtls_str_cat (line, sizeof (line), tmp);
                    }
                  else
                    break;
                }
              MHD__gnutls_write_log ("%s\n", line);
            }
        }
    }

  retval = n + session->internals.record_send_buffer_prev_size;

  session->internals.record_send_buffer.length = 0;
  session->internals.record_send_buffer_prev_size = 0;

  return retval;

}
Ejemplo n.º 14
0
/* This function is like read. But it does not return -1 on error.
 * It does return MHD_gnutls_errno instead.
 *
 * Flags are only used if the default recv() function is being used.
 */
static ssize_t
MHD__gnutls_read (MHD_gtls_session_t session, void *iptr,
                  size_t sizeOfPtr, int flags)
{
  size_t left;
  ssize_t i = 0;
  char *ptr = iptr;
  MHD_gnutls_transport_ptr_t fd = session->internals.transport_recv_ptr;

  session->internals.direction = 0;

  left = sizeOfPtr;
  while (left > 0)
    {
      session->internals.errnum = 0;
      if (session->internals.MHD__gnutls_pull_func == NULL)
        {
          i =
            recv (GNUTLS_POINTER_TO_INT (fd), &ptr[sizeOfPtr - left], left,
                  flags);
#if HAVE_WINSOCK
          if (i < 0)
            {
              int tmperr = WSAGetLastError ();
              switch (tmperr)
                {
                case WSAEWOULDBLOCK:
                  session->internals.errnum = EAGAIN;
                  break;

                case WSAEINTR:
                  session->internals.errnum = EINTR;
                  break;

                default:
                  session->internals.errnum = EIO;
                  break;
                }
              WSASetLastError (tmperr);
            }
#endif
        }
      else
	i = session->internals.MHD__gnutls_pull_func (fd,
						      &ptr[sizeOfPtr - left],
						      left);
      if (i < 0)
        {
          int err = session->internals.errnum ? session->internals.errnum
            : errno;
          if ( (err == EAGAIN) || (err == EINTR) )
            {
              if (sizeOfPtr - left > 0)
		goto finish;       
              MHD_gnutls_assert ();         
              if (err == EAGAIN)
                return GNUTLS_E_AGAIN;
              return GNUTLS_E_INTERRUPTED;
            }
          else
            {
              MHD_gnutls_assert ();
              return GNUTLS_E_PULL_ERROR;
            }
        }
      else
        {
          if (i == 0)
            break;              /* EOF */
        }
      left -= i;
    }

finish:
  return (sizeOfPtr - left);
}
Ejemplo n.º 15
0
/* This function is like read. But it does not return -1 on error.
 * It does return gnutls_errno instead.
 *
 * Flags are only used if the default recv() function is being used.
 */
static ssize_t
_gnutls_read (gnutls_session_t session, void *iptr,
	      size_t sizeOfPtr, int flags)
{
  size_t left;
  ssize_t i = 0;
  char *ptr = iptr;
  unsigned j, x, sum = 0;
  gnutls_transport_ptr_t fd = session->internals.transport_recv_ptr;

  session->internals.direction = 0;

  left = sizeOfPtr;
  while (left > 0)
    {

      session->internals.errnum = 0;

      if (session->internals._gnutls_pull_func == NULL)
	{
	  i = recv (GNUTLS_POINTER_TO_INT (fd), &ptr[sizeOfPtr - left],
		    left, flags);
#if HAVE_WINSOCK2_H
	  if (i < 0)
	    {
	      int tmperr = WSAGetLastError ();
	      switch (tmperr)
		{
		case WSAEWOULDBLOCK:
		  session->internals.errnum = EAGAIN;
		  break;

		case WSAEINTR:
		  session->internals.errnum = EINTR;
		  break;

		default:
		  session->internals.errnum = EIO;
		  break;
		}
	      WSASetLastError (tmperr);
	    }
#endif
	}
      else
	i = session->internals._gnutls_pull_func (fd,
						  &ptr[sizeOfPtr -
						       left], left);

      if (i < 0)
	{
	  int err = session->internals.errnum ? session->internals.errnum
	    : errno;

	  _gnutls_read_log ("READ: %d returned from %p, errno=%d gerrno=%d\n",
			    i, fd, errno, session->internals.errnum);

	  if (err == EAGAIN || err == EINTR)
	    {
	      if (sizeOfPtr - left > 0)
		{

		  _gnutls_read_log ("READ: returning %d bytes from %p\n",
				    sizeOfPtr - left, fd);

		  goto finish;
		}
	      gnutls_assert ();

	      if (err == EAGAIN)
		return GNUTLS_E_AGAIN;
	      return GNUTLS_E_INTERRUPTED;
	    }
	  else
	    {
	      gnutls_assert ();
	      return GNUTLS_E_PULL_ERROR;
	    }
	}
      else
	{

	  _gnutls_read_log ("READ: Got %d bytes from %p\n", i, fd);

	  if (i == 0)
	    break;		/* EOF */
	}

      left -= i;

    }

finish:

  if (_gnutls_log_level >= 7)
    {
      char line[128];
      char tmp[16];


      _gnutls_read_log ("READ: read %d bytes from %p\n",
			(sizeOfPtr - left), fd);

      for (x = 0; x < ((sizeOfPtr - left) / 16) + 1; x++)
	{
	  line[0] = 0;

	  sprintf (tmp, "%.4x - ", x);
	  _gnutls_str_cat (line, sizeof (line), tmp);

	  for (j = 0; j < 16; j++)
	    {
	      if (sum < (sizeOfPtr - left))
		{
		  sprintf (tmp, "%.2x ", ((unsigned char *) ptr)[sum++]);
		  _gnutls_str_cat (line, sizeof (line), tmp);
		}
	    }
	  _gnutls_read_log ("%s\n", line);
	}
    }

  return (sizeOfPtr - left);
}