int
SSL_pending (SSL * ssl)
{
  if (ssl->ssl_peek_avail)
    return ssl->ssl_peek_avail;
  return gnutls_record_check_pending (ssl->gnutls_state);
}
Exemple #2
0
static gint ssl_read(gnutls_session_t ssl, gchar *buf, gint len)
{
	gint r;

	if (gnutls_record_check_pending(ssl) == 0) {
		if (fd_check_io(GPOINTER_TO_INT(gnutls_transport_get_ptr(ssl)), G_IO_IN) < 0)
			return -1;
	}

	while (1) {
		r = gnutls_record_recv(ssl, buf, len);
		if (r > 0)
			return r;

		switch (r) {
		case 0: /* closed connection */
			return -1;

		case GNUTLS_E_REHANDSHAKE:
			do {
				r = gnutls_handshake(ssl);
			} while (r == GNUTLS_E_AGAIN || r == GNUTLS_E_INTERRUPTED);
			break; /* re-receive */
		case GNUTLS_E_AGAIN:
		case GNUTLS_E_INTERRUPTED:
			errno = EAGAIN;
			return -1;

		default:
			return -1;
		}
	}

}
Exemple #3
0
static int
wgnutls_poll (int fd, double timeout, int wait_for, void *arg)
{
  struct wgnutls_transport_context *ctx = arg;
  return ctx->peeklen || gnutls_record_check_pending (ctx->session)
    || select_fd (fd, timeout, wait_for);
}
/**
 * This function was created to handle per-connection processing that
 * has to happen even if the socket cannot be read or written to.  All
 * implementations (multithreaded, external select, internal select)
 * call this function.
 *
 * @param connection being handled
 * @return MHD_YES if we should continue to process the
 *         connection (not dead yet), MHD_NO if it died
 */
static int
MHD_tls_connection_handle_idle (struct MHD_Connection *connection)
{
  unsigned int timeout;

#if DEBUG_STATES
  MHD_DLOG (connection->daemon, "%s: state: %s\n",
            __FUNCTION__, MHD_state_to_string (connection->state));
#endif
  timeout = connection->connection_timeout;
  if ( (timeout != 0) && (time (NULL) - timeout > connection->last_activity))
    MHD_connection_close (connection,
			  MHD_REQUEST_TERMINATED_TIMEOUT_REACHED);
  switch (connection->state)
    {
      /* on newly created connections we might reach here before any reply has been received */
    case MHD_TLS_CONNECTION_INIT:
      return MHD_YES;
      /* close connection if necessary */
    case MHD_CONNECTION_CLOSED:
      gnutls_bye (connection->tls_session, GNUTLS_SHUT_RDWR);
      return MHD_connection_handle_idle (connection);
    default:
      if ( (0 != gnutls_record_check_pending (connection->tls_session)) &&
	   (MHD_YES != MHD_tls_connection_handle_read (connection)) )
	return MHD_YES;
      return MHD_connection_handle_idle (connection);
    }
  return MHD_YES;
}
Exemple #5
0
static int readable_gnutls(ne_socket *sock, int secs)
{
    if (gnutls_record_check_pending(sock->ssl)) {
        return 0;
    }
    return readable_raw(sock, secs);
}
Exemple #6
0
static gboolean ssl_sock_check(GSource *source)
{
	SockInfo *sock = ((SockSource *)source)->sock;
	struct timeval timeout = {0, 0};
	fd_set fds;
	GIOCondition condition = 0;
        
	if (!sock || !sock->sock)
		return FALSE;

	condition = sock->condition;

	if ((condition & G_IO_IN) == G_IO_IN &&
	    gnutls_record_check_pending(sock->ssl) != 0)
		return TRUE;

	FD_ZERO(&fds);
	FD_SET(sock->sock, &fds);

	select(sock->sock + 1,
	       (condition & G_IO_IN)  ? &fds : NULL,
	       (condition & G_IO_OUT) ? &fds : NULL,
	       NULL, &timeout);

	return FD_ISSET(sock->sock, &fds) != 0;
}
Exemple #7
0
int rfbssl_pending(rfbClientPtr cl)
{
    struct rfbssl_ctx *ctx = (struct rfbssl_ctx *)cl->sslctx;
    int ret = ctx->peeklen;

    if (ret <= 0)
	ret = gnutls_record_check_pending(ctx->session);

    return ret;
}
static int wait_read(mailstream_low * s)
{
  fd_set fds_read;
  struct timeval timeout;
  int fd;
  struct mailstream_ssl_data * ssl_data;
  int max_fd;
  int r;
  int cancelled;
  int got_data;
#ifdef WIN32
  HANDLE event;
#endif
  
  ssl_data = (struct mailstream_ssl_data *) s->data;
  timeout = mailstream_network_delay;
  
#ifdef USE_GNUTLS
  if (gnutls_record_check_pending(ssl_data->session) != 0)
    return 0;
#endif

  FD_ZERO(&fds_read);
  fd = mailstream_cancel_get_fd(ssl_data->cancel);
  FD_SET(fd, &fds_read);
#ifdef WIN32
  event = CreateEvent(NULL, TRUE, FALSE, NULL);
  WSAEventSelect(ssl_data->fd, event, FD_READ | FD_CLOSE);
  FD_SET(event, &fds_read);
  r = WaitForMultipleObjects(fds_read.fd_count, fds_read.fd_array, FALSE, timeout.tv_sec * 1000 + timeout.tv_usec / 1000);
  if (WAIT_TIMEOUT == r)
    return -1;
  
  cancelled = (fds_read.fd_array[r - WAIT_OBJECT_0] == fd);
  got_data = (fds_read.fd_array[r - WAIT_OBJECT_0] == event);
#else
  FD_SET(ssl_data->fd, &fds_read);
  max_fd = ssl_data->fd;
  if (fd > max_fd)
    max_fd = fd;
  r = select(max_fd + 1, &fds_read, NULL, NULL, &timeout);
  if (r <= 0)
    return -1;
  
  cancelled = (FD_ISSET(fd, &fds_read));
  got_data = FD_ISSET(ssl_data->fd, &fds_read);
#endif
  if (cancelled) {
    /* cancelled */
    mailstream_cancel_ack(ssl_data->cancel);
    return -1;
  }
  
  return 0;
}
Exemple #9
0
ssize_t TCPStream::dataAvailable() {

    if(secure) {

        return gnutls_record_check_pending(*m_session);
    }
    else {
        int nbrBytes = 0;
        ioctl(m_sd,FIONREAD,&nbrBytes);
        return nbrBytes;
    }
}
Exemple #10
0
/* returns IN_KEYBOARD for keyboard input and IN_NET for network input
 */
static int check_net_or_keyboard_input(socket_st* hd)
{
  int maxfd;
  fd_set rset;
  int err;
  struct timeval tv;

  do
    {
      FD_ZERO (&rset);
      FD_SET (hd->fd, &rset);

#ifndef _WIN32
      FD_SET (fileno (stdin), &rset);
      maxfd = MAX (fileno (stdin), hd->fd);
#else
      maxfd = hd->fd;
#endif

      tv.tv_sec = 0;
      tv.tv_usec = 50 * 1000;

      if (hd->secure == 1)
        if (gnutls_record_check_pending(hd->session))
          return IN_NET;

      err = select (maxfd + 1, &rset, NULL, NULL, &tv);
      if (err < 0)
        continue;

      if (FD_ISSET (hd->fd, &rset))
        return IN_NET;

#ifdef _WIN32
      {
        int state;
        state = WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 200); 
        
        if (state == WAIT_OBJECT_0)
          return IN_KEYBOARD;
      }
#else
      if (FD_ISSET (fileno (stdin), &rset))
        return IN_KEYBOARD;
#endif
    }
  while(err == 0);
  
  return IN_NONE;
}
Exemple #11
0
static inline void
tls_signal_pending(struct gnutella_socket *s)
{
    size_t n = gnutls_record_check_pending(tls_socket_get_session(s));

    if (n > 0) {
        int saved_errno = errno;

        if (GNET_PROPERTY(tls_debug) > 1) {
            g_debug("%s: pending=%zu", G_STRFUNC, n);
        }
        inputevt_set_readable(s->file_desc);
        errno = saved_errno;
    }
}
Exemple #12
0
int ssl_pending( void *conn )
{
	if( conn == NULL )
		return 0;
	
	if( !((struct scd*)conn)->established )
	{
		ssl_errno = SSL_NOHANDSHAKE;
		return 0;
	}

#if GNUTLS_VERSION_NUMBER >= 0x03000d && GNUTLS_VERSION_NUMBER <= 0x030012
	if( ssl_errno == SSL_AGAIN )
		return 0;
#endif
	
	return gnutls_record_check_pending( ((struct scd*)conn)->session ) != 0;
}
Exemple #13
0
static int
tlsg_sb_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg )
{
	struct tls_data		*p;
	
	assert( sbiod != NULL );
	assert( sbiod->sbiod_pvt != NULL );

	p = (struct tls_data *)sbiod->sbiod_pvt;
	
	if ( opt == LBER_SB_OPT_GET_SSL ) {
		*((tlsg_session **)arg) = p->session;
		return 1;
		
	} else if ( opt == LBER_SB_OPT_DATA_READY ) {
		if( gnutls_record_check_pending( p->session->session ) > 0 ) {
			return 1;
		}
	}
	
	return LBER_SBIOD_CTRL_NEXT( sbiod, opt, arg );
}
Exemple #14
0
static int
wgnutls_peek (int fd, char *buf, int bufsize, void *arg)
{
  int read = 0;
  struct wgnutls_transport_context *ctx = arg;
  int offset = MIN (bufsize, ctx->peeklen);
  if (bufsize > sizeof ctx->peekbuf)
    bufsize = sizeof ctx->peekbuf;

  if (ctx->peeklen)
    memcpy (buf, ctx->peekbuf, offset);

  if (bufsize > offset)
    {
      if (gnutls_record_check_pending (ctx->session) <= 0
          && select_fd (fd, 0.0, WAIT_FOR_READ) <= 0)
        read = 0;
      else
        read = gnutls_record_recv (ctx->session, buf + offset,
                                   bufsize - offset);
        
      if (read < 0)
        {
          if (offset)
            read = 0;
          else
            return read;
        }

      if (read > 0)
        {
          memcpy (ctx->peekbuf + offset, buf + offset,
                  read);
          ctx->peeklen += read;
        }
    }

  return offset + read;
}
Exemple #15
0
/* returns IN_KEYBOARD for keyboard input and IN_NET for network input
 */
static int check_net_or_keyboard_input(socket_st* hd)
{
  int maxfd;
  fd_set rset;
  int err;
  struct timeval tv;

  do
    {
      FD_ZERO (&rset);
      FD_SET (fileno (stdin), &rset);
      FD_SET (hd->fd, &rset);

      maxfd = MAX (fileno (stdin), hd->fd);
      tv.tv_sec = 0;
      tv.tv_usec = 500 * 1000;

      if (hd->secure == 1)
        if (gnutls_record_check_pending(hd->session))
          return IN_NET;

      err = select (maxfd + 1, &rset, NULL, NULL, &tv);
      if (err < 0)
        continue;

      if (FD_ISSET (hd->fd, &rset))
        return IN_NET;


      if (FD_ISSET (fileno (stdin), &rset))
        return IN_KEYBOARD;
    }
  while(err == 0);
  
  return IN_NONE;
}
Exemple #16
0
/**
 * This function was created to handle per-connection processing that
 * has to happen even if the socket cannot be read or written to.  All
 * implementations (multithreaded, external select, internal select)
 * call this function.
 *
 * @param connection being handled
 * @return #MHD_YES if we should continue to process the
 *         connection (not dead yet), #MHD_NO if it died
 */
static int
MHD_tls_connection_handle_idle (struct MHD_Connection *connection)
{
  unsigned int timeout;

#if DEBUG_STATES
  MHD_DLOG (connection->daemon,
            _("In function %s handling connection at state: %s\n"),
            __FUNCTION__,
            MHD_state_to_string (connection->state));
#endif
  timeout = connection->connection_timeout;
  if ( (timeout != 0) &&
       (timeout <= (MHD_monotonic_sec_counter() - connection->last_activity)))
    MHD_connection_close_ (connection,
                           MHD_REQUEST_TERMINATED_TIMEOUT_REACHED);
  switch (connection->state)
    {
      /* on newly created connections we might reach here before any reply has been received */
    case MHD_TLS_CONNECTION_INIT:
      break;
      /* close connection if necessary */
    case MHD_CONNECTION_CLOSED:
      return MHD_connection_handle_idle (connection);
    default:
      if ( (0 != gnutls_record_check_pending (connection->tls_session)) &&
	   (MHD_YES != MHD_tls_connection_handle_read (connection)) )
	return MHD_YES;
      return MHD_connection_handle_idle (connection);
    }
#ifdef EPOLL_SUPPORT
  return MHD_connection_epoll_update_ (connection);
#else
  return MHD_YES;
#endif
}
Exemple #17
0
static int wait_read(mailstream_low * s)
{
  struct timeval timeout;
  int cancellation_fd;
  struct mailstream_ssl_data * ssl_data;
  int r;
  int cancelled;
#if defined(WIN32)
  fd_set fds_read;
  HANDLE event;
#elif USE_POLL
  struct pollfd pfd[2];
#else
  fd_set fds_read;
  int max_fd;
#endif

  ssl_data = (struct mailstream_ssl_data *) s->data;
  if (s->timeout == 0) {
    timeout = mailstream_network_delay;
  }
  else {
		timeout.tv_sec = s->timeout;
    timeout.tv_usec = 0;
  }
  
#ifdef USE_GNUTLS
  if (gnutls_record_check_pending(ssl_data->session) != 0)
    return 0;
#endif

  cancellation_fd = mailstream_cancel_get_fd(ssl_data->cancel);
#if defined(WIN32)
  FD_ZERO(&fds_read);
  FD_SET(cancellation_fd, &fds_read);
  event = CreateEvent(NULL, TRUE, FALSE, NULL);
  WSAEventSelect(ssl_data->fd, event, FD_READ | FD_CLOSE);
  FD_SET(event, &fds_read);
  r = WaitForMultipleObjects(fds_read.fd_count, fds_read.fd_array, FALSE, timeout.tv_sec * 1000 + timeout.tv_usec / 1000);
  if (WAIT_TIMEOUT == r) {
    WSAEventSelect(ssl_data->fd, event, 0);
    CloseHandle(event);
    return -1;
  }
  
  cancelled = (fds_read.fd_array[r - WAIT_OBJECT_0] == cancellation_fd);
  WSAEventSelect(ssl_data->fd, event, 0);
  CloseHandle(event);
#elif USE_POLL
  pfd[0].fd = ssl_data->fd;
  pfd[0].events = POLLIN;
  pfd[0].revents = 0;

  pfd[1].fd = cancellation_fd;
  pfd[1].events = POLLIN;
  pfd[1].revents = 0;

  r = poll(&pfd[0], 2, timeout.tv_sec * 1000 + timeout.tv_usec / 1000);
  if (r <= 0)
    return -1;
  
  cancelled = pfd[1].revents & POLLIN;
#else
  FD_ZERO(&fds_read);
  FD_SET(cancellation_fd, &fds_read);
  FD_SET(ssl_data->fd, &fds_read);
  max_fd = cancellation_fd > ssl_data->fd ? cancellation_fd : ssl_data->fd;
  r = select(max_fd + 1, &fds_read, NULL, NULL, &timeout);
  if (r <= 0)
      return -1;
  cancelled = FD_ISSET(cancellation_fd, &fds_read);
#endif
  if (cancelled) {
    /* cancelled */
    mailstream_cancel_ack(ssl_data->cancel);
    return -1;
  }
  
  return 0;
}
size_t session::check_pending () const
{
    return gnutls_record_check_pending (s);
}
Exemple #19
0
bool SocketRWCommon::hasTlsPendingData() const {
	if (tlsActive)
		return (gnutls_record_check_pending(tls) > 0);
	else
		return false;
}
static gint
xfce_mailwatch_net_conn_recv_internal(XfceMailwatchNetConn *net_conn,
                                      guchar *buf,
                                      gsize buf_len,
                                      gboolean block,
                                      GError **error)
{
    gint ret, bin = 0, code = XFCE_MAILWATCH_ERROR_FAILED;
    const gchar *reason;
    TIMER_INIT;

    TIMER_START;
    do {
        fd_set rfd;
        struct timeval tv = { 1, 0 };

        FD_ZERO(&rfd);
        FD_SET(net_conn->fd, &rfd);
        if(!block)
            tv.tv_sec = 0;

#ifdef HAVE_SSL_SUPPORT
        /* Read data from the gnutls read buffer, first. */
        if (net_conn->is_secure
            && (ret = gnutls_record_check_pending(net_conn->gt_session)) > 0) {
            break;
        }
#endif
        ret = select(FD_SETSIZE, &rfd, NULL, NULL, &tv);
        if(ret > 0 && FD_ISSET(net_conn->fd, &rfd))
            break;
        else if(ret < 0 && errno != EINTR) {
            g_set_error(error, XFCE_MAILWATCH_ERROR,
                        XFCE_MAILWATCH_ERROR_FAILED, "%s", strerror(errno));
            return -1;
        } else if(!block)
            return 0;
    } while((ret == 0 || (ret < 0 && errno == EINTR))
            && !TIMER_EXPIRED(RECV_TIMEOUT) && SHOULD_CONTINUE(net_conn));

    if(ret < 0 && errno != EINTR) {
        if(error) {
            g_set_error(error, XFCE_MAILWATCH_ERROR,
                        XFCE_MAILWATCH_ERROR_FAILED, "%s", strerror(errno));
        }
        return -1;
    } else if(!SHOULD_CONTINUE(net_conn)) {
        if(error) {
            g_set_error(error, XFCE_MAILWATCH_ERROR,
                        XFCE_MAILWATCH_ERROR_ABORTED, "%s",
                        _("Operation aborted"));
        }
        return -1;
    } else if(TIMER_EXPIRED(RECV_TIMEOUT)) {
        if(error) {
            g_set_error(error, XFCE_MAILWATCH_ERROR,
                        XFCE_MAILWATCH_ERROR_FAILED, "%s",
                        strerror(ETIMEDOUT));
        }
        return -1;
    }

#ifdef HAVE_SSL_SUPPORT
    if(net_conn->is_secure) {
        gint gret;
        code = XFCE_MAILWATCH_ERROR_FAILED;

        TIMER_START;
        do {
            gret = gnutls_record_recv(net_conn->gt_session, buf, buf_len);

            if(gret == GNUTLS_E_REHANDSHAKE) {
                if(!xfce_mailwatch_net_conn_tls_handshake(net_conn, error))
                    return -1;
                gret = GNUTLS_E_AGAIN;
            }
        } while((gret == GNUTLS_E_INTERRUPTED || gret == GNUTLS_E_AGAIN)
                && !TIMER_EXPIRED(RECV_TIMEOUT) && SHOULD_CONTINUE(net_conn));
        
        if(gret < 0) {
            if(error) {
                if(!SHOULD_CONTINUE(net_conn)) {
                    code = XFCE_MAILWATCH_ERROR_ABORTED;
                    reason = _("Operation aborted");
                } else if(TIMER_EXPIRED(RECV_TIMEOUT))
                    reason = strerror(ETIMEDOUT);
                else
                    reason = gnutls_strerror(gret);

                g_set_error(error, XFCE_MAILWATCH_ERROR, code,
                            _("Failed to receive encrypted data: %s"),
                            reason);
            }

            bin = -1;
        } else
            bin = gret;
    } else
#endif
    {
        gint pret;
        code = XFCE_MAILWATCH_ERROR_FAILED;

        TIMER_START;
        do {
            pret = recv(net_conn->fd, buf, buf_len, MSG_NOSIGNAL);
        } while(pret < 0 && (errno == EINTR || errno == EAGAIN)
                && !TIMER_EXPIRED(RECV_TIMEOUT) && SHOULD_CONTINUE(net_conn));

        if(pret < 0) {
            if(error) {
                if(!SHOULD_CONTINUE(net_conn)) {
                    code = XFCE_MAILWATCH_ERROR_ABORTED;
                    reason = _("Operation aborted");
                } else if(TIMER_EXPIRED(RECV_TIMEOUT))
                    reason = strerror(ETIMEDOUT);
                else
                    reason = strerror(errno);

                g_set_error(error, XFCE_MAILWATCH_ERROR, code,
                            _("Failed to receive data: %s"), reason);
            }
            bin = -1;
        } else
            bin = pret;
    }

    return bin;
}
Exemple #21
0
int
SSL_pending (SSL * ssl)
{
  return gnutls_record_check_pending (ssl->gnutls_state);
}
Exemple #22
0
int tls_pending(tls_t *tls)
{
    return gnutls_record_check_pending (tls->session);
}
Exemple #23
0
/** Handles one client.
 * This one connects to the remote server, and proxies every traffic
 * between our client and the server.
 *
 * @param config is the main CryWrap configuration structure.
 * @param insock is the socket through which the client sends input.
 * @param outsock is the socket through which we send output.
 *
 * @note Exits on error.
 */
static int
_crywrap_do_one(const crywrap_config_t * config, int insock, int outsock)
{
	int sock, ret, tls_pending;
	gnutls_session_t session;
	char buffer[_CRYWRAP_MAXBUF + 2];
	fd_set fdset;
	unsigned int status = 0;
	struct sockaddr_storage faddr;
	socklen_t socklen = sizeof(struct sockaddr_storage);
	char peer_name[NI_MAXHOST];

	/* Log the connection */
	if (getpeername(insock, (struct sockaddr *) &faddr, &socklen) != 0)
		cry_error("getpeername(): %s", strerror(errno));
	else {
		getnameinfo((struct sockaddr *) &faddr,
			    sizeof(struct sockaddr_storage), peer_name,
			    sizeof(peer_name), NULL, 0, NI_NUMERICHOST);
		cry_log("Accepted connection from %s on %d to %s/%d",
			peer_name, insock, config->dest.host,
			config->dest.port);
	}

	/* Do the handshake with our peer */
	session = _crywrap_tls_session_create(config);
	gnutls_transport_set_ptr2(session,
				  (gnutls_transport_ptr_t) insock,
				  (gnutls_transport_ptr_t) outsock);

	do {
		ret = gnutls_handshake(session);
	}
	while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED);

	if (ret < 0) {
		cry_error("Handshake failed: %s", gnutls_strerror(ret));
		gnutls_alert_send_appropriate(session, ret);
		goto error;
	}

	/* Verify the client's certificate, if any. */
	if (config->verify) {
		ret = gnutls_certificate_verify_peers2(session, &status);
		if (ret < 0)
			cry_log
			    ("Error getting certificate from client: %s",
			     gnutls_strerror(ret));

		if (ret == 0 && status != 0) {
			if (status & GNUTLS_CERT_INVALID)
				cry_log("%s",
					"Client certificate not trusted or invalid");
		}

		if (config->verify > 0 && status != 0) {
			ret = -1;
			gnutls_alert_send(session, GNUTLS_AL_FATAL,
					  GNUTLS_A_INSUFFICIENT_SECURITY);
			goto error;
		}
	}

	/* Connect to the remote host */
	sock = _crywrap_remote_connect(config->dest.addr,
				       htons(config->dest.port));

	for (;;) {
		FD_ZERO(&fdset);
		FD_SET(insock, &fdset);
		FD_SET(sock, &fdset);

		memset(buffer, 0, _CRYWRAP_MAXBUF + 1);

		tls_pending = 0;

		if (gnutls_record_check_pending(session) > 0)
			tls_pending = 1;
		else {
			select(sock + 1, &fdset, NULL, NULL, NULL);
			if (FD_ISSET(insock, &fdset))
				tls_pending = 1;
		}
		/* TLS client */
		if (tls_pending != 0) {
			ret =
			    gnutls_record_recv(session, buffer,
					       _CRYWRAP_MAXBUF);
			if (ret == 0) {
				cry_log("%s",
					"Peer has closed the GNUTLS connection");
				break;
			} else if (ret < 0) {
				cry_log("Received corrupted data: %s.",
					gnutls_strerror(ret));
				break;
			} else
				send(sock, buffer, ret, 0);
		}

		/* Remote server */
		if (FD_ISSET(sock, &fdset)) {
			ret = recv(sock, buffer, _CRYWRAP_MAXBUF, 0);
			if (ret == 0) {
				cry_log("%s",
					"Server has closed the connection");
				break;
			} else if (ret < 0) {
				cry_log("Received corrupted data: %s.",
					strerror(errno));
				break;
			} else {
				int r, o = 0;

				do {
					r = gnutls_record_send(session,
							       &buffer[o],
							       ret - o);
					o += r;
				} while (r > 0 && ret > o);

				if (r < 0)
					cry_log
					    ("Received corrupt data: %s",
					     gnutls_strerror(r));
			}
		}
	}

      error:
	gnutls_bye(session, GNUTLS_SHUT_WR);
	gnutls_deinit(session);
	close(insock);
	close(outsock);

	return (ret == 0) ? 0 : 1;
}
Exemple #24
0
/*
 * Return zero if session tickets haven't been enabled.
 */
int _gnutls_recv_new_session_ticket(gnutls_session_t session)
{
	uint8_t *p;
	int data_size;
	gnutls_buffer_st buf;
	uint16_t ticket_len;
	int ret;
	session_ticket_ext_st *priv = NULL;
	gnutls_ext_priv_data_t epriv;

	if (session->internals.flags & GNUTLS_NO_TICKETS)
		return 0;
	if (!session->internals.session_ticket_renew)
		return 0;

	/* This is the last flight and peer cannot be sure
	 * we have received it unless we notify him. So we
	 * wait for a message and retransmit if needed. */
	if (IS_DTLS(session) && !_dtls_is_async(session)) {
		unsigned have;
		mbuffer_st *bufel = NULL;

		have = gnutls_record_check_pending(session) +
		       record_check_unprocessed(session);

		if (have != 0) {
			bufel = _mbuffer_head_get_first(&session->internals.record_buffer, NULL);
		}

		if (have == 0 || (bufel && bufel->type != GNUTLS_HANDSHAKE)) {
			ret = _dtls_wait_and_retransmit(session);
			if (ret < 0)
				return gnutls_assert_val(ret);
		}
	}

	ret = _gnutls_recv_handshake(session,
				     GNUTLS_HANDSHAKE_NEW_SESSION_TICKET,
				     0, &buf);
	if (ret < 0)
		return gnutls_assert_val_fatal(ret);

	p = buf.data;
	data_size = buf.length;

	DECR_LENGTH_COM(data_size, 4, ret =
			GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
			goto error);
	/* skip over lifetime hint */
	p += 4;

	DECR_LENGTH_COM(data_size, 2, ret =
			GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
			goto error);
	ticket_len = _gnutls_read_uint16(p);
	p += 2;

	DECR_LENGTH_COM(data_size, ticket_len, ret =
			GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
			goto error);

	priv = gnutls_calloc(1, sizeof(*priv));
	if (!priv) {
		gnutls_assert();
		ret = GNUTLS_E_MEMORY_ERROR;
		goto error;
	}
	priv->session_ticket =
	    gnutls_realloc_fast(priv->session_ticket, ticket_len);
	if (!priv->session_ticket) {
		gnutls_free(priv);
		gnutls_assert();
		ret = GNUTLS_E_MEMORY_ERROR;
		goto error;
	}
	memcpy(priv->session_ticket, p, ticket_len);
	priv->session_ticket_len = ticket_len;
	epriv = priv;

	/* Discard the current session ID.  (RFC5077 3.4) */
	ret =
	    _gnutls_generate_session_id(session->security_parameters.
					session_id,
					&session->security_parameters.
					session_id_size);
	if (ret < 0) {
		gnutls_assert();
		session_ticket_deinit_data(epriv);
		ret = GNUTLS_E_INTERNAL_ERROR;
		goto error;
	}
	ret = 0;

	_gnutls_handshake_log
		    ("HSK[%p]: received session ticket\n", session);
	session->internals.hsk_flags |= HSK_TICKET_RECEIVED;

	_gnutls_hello_ext_set_priv(session,
			GNUTLS_EXTENSION_SESSION_TICKET,
			epriv);

      error:
	_gnutls_buffer_clear(&buf);

	return ret;
}
Exemple #25
0
size_t					/* O - Bytes available */
_httpTLSPending(http_t *http)		/* I - HTTP connection */
{
  return (gnutls_record_check_pending(http->tls));
}
Exemple #26
0
bool_t SSLi_data_pending(SSL_handle_t *session)
{
	return gnutls_record_check_pending(*session);
}
Exemple #27
0
int _gnutls_recv_new_session_ticket(gnutls_session_t session)
{
    uint8_t *p;
    int data_size;
    gnutls_buffer_st buf;
    uint16_t ticket_len;
    int ret;
    session_ticket_ext_st *priv = NULL;
    extension_priv_data_t epriv;

    ret =
        _gnutls_ext_get_session_data(session,
                                     GNUTLS_EXTENSION_SESSION_TICKET,
                                     &epriv);
    if (ret < 0) {
        gnutls_assert();
        return 0;
    }
    priv = epriv;

    if (!priv->session_ticket_renew)
        return 0;

    /* This is the last flight and peer cannot be sure
     * we have received it unless we notify him. So we
     * wait for a message and retransmit if needed. */
    if (IS_DTLS(session) && !_dtls_is_async(session) &&
            (gnutls_record_check_pending(session) +
             record_check_unprocessed(session)) == 0) {
        ret = _dtls_wait_and_retransmit(session);
        if (ret < 0)
            return gnutls_assert_val(ret);
    }

    ret = _gnutls_recv_handshake(session,
                                 GNUTLS_HANDSHAKE_NEW_SESSION_TICKET,
                                 0, &buf);
    if (ret < 0)
        return gnutls_assert_val_fatal(ret);

    p = buf.data;
    data_size = buf.length;

    DECR_LENGTH_COM(data_size, 4, ret =
                        GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
                    goto error);
    /* skip over lifetime hint */
    p += 4;

    DECR_LENGTH_COM(data_size, 2, ret =
                        GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
                    goto error);
    ticket_len = _gnutls_read_uint16(p);
    p += 2;

    DECR_LENGTH_COM(data_size, ticket_len, ret =
                        GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
                    goto error);
    priv->session_ticket =
        gnutls_realloc_fast(priv->session_ticket, ticket_len);
    if (!priv->session_ticket) {
        gnutls_assert();
        ret = GNUTLS_E_MEMORY_ERROR;
        goto error;
    }
    memcpy(priv->session_ticket, p, ticket_len);
    priv->session_ticket_len = ticket_len;

    /* Discard the current session ID.  (RFC5077 3.4) */
    ret =
        _gnutls_generate_session_id(session->security_parameters.
                                    session_id,
                                    &session->security_parameters.
                                    session_id_size);
    if (ret < 0) {
        gnutls_assert();
        gnutls_free(priv->session_ticket);
        priv->session_ticket = NULL;
        ret = GNUTLS_E_INTERNAL_ERROR;
        goto error;
    }
    ret = 0;

error:
    _gnutls_buffer_clear(&buf);

    return ret;
}