예제 #1
0
static ssize_t
tls_write_intern(struct wrap_io *wio, const void *buf, size_t size)
{
    struct gnutella_socket *s = wio->ctx;
    ssize_t ret;

    g_assert((0 == s->tls.snarf) ^ (NULL == buf));
    g_assert((0 == s->tls.snarf) ^ (0 == size));

    size = tls_adjust_send_size(s, size);
    ret = gnutls_record_send(tls_socket_get_session(s), buf, size);
    if (ret < 0) {
        switch (ret) {
        case GNUTLS_E_INTERRUPTED:
        case GNUTLS_E_AGAIN:
            if (0 == s->tls.snarf) {
                s->tls.snarf = size;
                ret = size;
            } else {
                errno = VAL_EAGAIN;
                ret = -1;
            }
            break;
        case GNUTLS_E_PULL_ERROR:
        case GNUTLS_E_PUSH_ERROR:
            /* Logging already done by tls_transport_debug() */
            errno = (SOCK_F_CONNRESET & s->flags) ? ECONNRESET : EIO;
            ret = -1;
            goto finish;

        default:
            if (GNET_PROPERTY(tls_debug)) {
                g_carp("tls_write(): gnutls_record_send(fd=%d) failed: "
                       "host=%s snarf=%zu error=\"%s\"",
                       s->file_desc, host_addr_port_to_string(s->addr, s->port),
                       s->tls.snarf, gnutls_strerror(ret));
            }
            errno = EIO;
            ret = -1;
            goto finish;
        }
    } else {

        if (s->tls.snarf) {
            g_assert(s->tls.snarf >= (size_t) ret);
            s->tls.snarf -= ret;
            errno = VAL_EAGAIN;
            ret = -1;
            goto finish;
        }
    }

    if (s->tls.snarf) {
        tls_socket_evt_change(s, INPUT_EVENT_WX);
    }

finish:
    g_assert(ret == (ssize_t) -1 || (size_t) ret <= size);
    return ret;
}
예제 #2
0
static ssize_t gnutls_Send (vlc_tls_t *tls, const void *buf, size_t length)
{
    gnutls_session_t session = tls->sys;
    ssize_t val = gnutls_record_send (session, buf, length);

    return (val < 0) ? gnutls_Error (tls, val) : val;
}
예제 #3
0
static void client(int sock)
{
	int err = 0;
	time_t started = time(0);
	const char* line = "foobar!";
	char buffer[8192];
	int len;

	session_init(sock, 0);

	killtimer_set();
	do {
		err = process_error(gnutls_handshake(session));
		if (err != 0) {
			int t = gnutls_dtls_get_timeout(session);
			await(sock, t ? t : 100);
		}
	} while (err != 0);
	process_error_or_timeout(err, time(0) - started);
	
	killtimer_set();
	die_on_error(gnutls_record_send(session, line, strlen(line)));
	
	do {
		await(sock, -1);
		len = process_error(gnutls_record_recv(session, buffer, sizeof(buffer)));
	} while (len < 0);

	if (len > 0 && strncmp(line, buffer, len) == 0) {
		exit(0);
	} else {
		exit(1);
	}
}
예제 #4
0
static void server(int sock)
{ 
	int err;
	time_t started = time(0);
	char buffer[8192];
	int len;

	session_init(sock, 1);

	await(sock, -1);

	killtimer_set();
	do {
		err = process_error(gnutls_handshake(session));
		if (err != 0) {
			int t = gnutls_dtls_get_timeout(session);
			await(sock, t ? t : 100);
		}
	} while (err != 0);
	process_error_or_timeout(err, time(0) - started);

	killtimer_set();
	do {
		await(sock, -1);
		len = process_error(gnutls_record_recv(session, buffer, sizeof(buffer)));
	} while (len < 0);

	die_on_error(gnutls_record_send(session, buffer, len));
	exit(0);
}
예제 #5
0
static int
tls_send (struct ikstls_data *data, const char *buf, size_t size)
{
	if (gnutls_record_send (data->sess, buf, size) < 0)
		return IKS_NET_RWERR;
	return IKS_OK;
}
예제 #6
0
파일: tls-gnu.c 프로젝트: fanf2/exim
int
tls_write(const uschar *buff, size_t len)
{
int outbytes;
int left = len;

DEBUG(D_tls) debug_printf("tls_do_write(%lx, %d)\n", (long) buff, left);
while (left > 0)
  {
  DEBUG(D_tls) debug_printf("gnutls_record_send(SSL, %lx, %d)\n", (long)buff,
    left);
  outbytes = gnutls_record_send(tls_session, CS buff, left);

  DEBUG(D_tls) debug_printf("outbytes=%d\n", outbytes);
  if (outbytes < 0)
    {
    record_io_error(outbytes, US"send", NULL);
    return -1;
    }
  if (outbytes == 0)
    {
    record_io_error(0, US"send", US"TLS channel closed on write");
    return -1;
    }

  left -= outbytes;
  buff += outbytes;
  }

return len;
}
예제 #7
0
static void do_reflect_stuff(gnutls_session_t session)
{
	char buf[64];
	unsigned buf_size;
	int ret;

	do {
		ret = gnutls_record_recv(session, buf, sizeof(buf));
		if (ret < 0) {
			fail("server: recv failed: %s\n", gnutls_strerror(ret));
			terminate();
		}

		if (ret == 0)
			break;

		buf_size = ret;
		if (debug) {
			fprintf(stderr, "server received: %.*s\n", buf_size, buf);
		}

		ret = gnutls_record_send(session, buf, buf_size);
		if (ret < 0) {
			fail("server: send failed: %s\n", gnutls_strerror(ret));
			terminate();
		}
	} while(1);

	/* do not wait for the peer to close the connection.
	 */
	gnutls_bye(session, GNUTLS_SHUT_WR);
}
예제 #8
0
int TlsSocket::Send(const char* buffer, int size)
{
#ifdef HAVE_LIBGNUTLS
	m_retCode = gnutls_record_send((gnutls_session_t)m_session, buffer, size);
#endif /* HAVE_LIBGNUTLS */

#ifdef HAVE_OPENSSL
	m_retCode = SSL_write((SSL*)m_session, buffer, size);
#endif /* HAVE_OPENSSL */

	if (m_retCode < 0)
	{
#ifdef HAVE_OPENSSL
		if (ERR_peek_error() == 0)
		{
			ReportError("Could not write to TLS-Socket: Connection closed by remote host");
		}
		else
#endif /* HAVE_OPENSSL */
		ReportError("Could not write to TLS-Socket");
		return -1;
	}

	return m_retCode;
}
예제 #9
0
파일: server.c 프로젝트: dmr0605/Kerberos
/* Send string to peer, via UDP/TCP/TLS, reporting any errors. */
void
kdc_send1 (struct listenspec *ls)
{
  ssize_t sent_bytes;

  do
#ifdef USE_STARTTLS
    if (ls->usetls)
      sent_bytes = gnutls_record_send (ls->session, ls->buf, ls->bufpos);
    else
#endif
      sent_bytes = sendto (ls->sockfd, ls->buf, ls->bufpos,
			   0, &ls->addr, ls->addrlen);
  while (sent_bytes == -1 && errno == EAGAIN);

  if (sent_bytes < 0)
    syslog (LOG_ERR, "Error writing %d bytes to %s on socket %d: %s",
	    ls->bufpos, ls->str, ls->sockfd, strerror (errno));
  else if ((size_t) sent_bytes > ls->bufpos)
    syslog (LOG_ERR, "Overlong write (%d > %d) to %s on socket %d",
	    sent_bytes, ls->bufpos, ls->str, ls->sockfd);
  else if ((size_t) sent_bytes < ls->bufpos)
    syslog (LOG_ERR, "Short write (%d < %d) to %s on socket %d",
	    sent_bytes, ls->bufpos, ls->str, ls->sockfd);
}
예제 #10
0
static ssize_t mailstream_low_ssl_write(mailstream_low * s,
                                        const void * buf, size_t count)
{
    struct mailstream_ssl_data * ssl_data;
    int r;

    ssl_data = (struct mailstream_ssl_data *) s->data;
    r = wait_write(s);
    if (r <= 0)
        return r;

    r = gnutls_record_send(ssl_data->session, buf, count);
    if (r > 0)
        return r;

    switch (r) {
    case 0:
        return -1;

    case GNUTLS_E_AGAIN:
    case GNUTLS_E_INTERRUPTED:
        return 0;

    default:
        return r;
    }
}
예제 #11
0
파일: tlslib.c 프로젝트: a1ive/ocserv-fork
ssize_t dtls_send(worker_st *ws, const void *data,
			size_t data_size)
{
	int ret;
	int left = data_size;
	const uint8_t* p = data;

	while(left > 0) {
		ret = gnutls_record_send(ws->dtls_session, p, data_size);
		if (ret < 0) {
			if (ret != GNUTLS_E_AGAIN && ret != GNUTLS_E_INTERRUPTED) {
				return ret;
			} else {
				/* do not cause mayhem */
				ms_sleep(20);
			}
		}

		if (ret > 0) {
			left -= ret;
			p += ret;
		}
	}

	return data_size;
}
예제 #12
0
size_t TLSSocket_GnuTLS::sendRawNonBlocking(const byte_t* buffer, const size_t count) {

	m_status &= ~(STATUS_WANT_WRITE | STATUS_WANT_READ);

	resetException();

	ssize_t ret = gnutls_record_send(
		*m_session->m_gnutlsSession,
		buffer, static_cast <size_t>(count)
	);

	throwException();

	if (ret < 0) {

		if (ret == GNUTLS_E_AGAIN) {

			if (gnutls_record_get_direction(*m_session->m_gnutlsSession) == 0) {
				m_status |= STATUS_WANT_READ;
			} else {
				m_status |= STATUS_WANT_WRITE;
			}

			return 0;
		}

		TLSSession_GnuTLS::throwTLSException("gnutls_record_send", static_cast <int>(ret));
	}

	return static_cast <size_t>(ret);
}
예제 #13
0
apr_status_t send_answer(socket_thread_data_t *td, const char *answer)
{
	apr_size_t msglen;
	apr_size_t sent;
	apr_size_t total_sent = 0;
	apr_status_t res;

	msglen = strlen(answer);
	if(td->tls_session == NULL)
	{
		while(total_sent < msglen)
		{
			sent = msglen;
			res = apr_socket_send(td->socket, answer + total_sent, &sent);
			if(res != APR_SUCCESS)
				return res;
			total_sent += sent;
		}
	}
	else
	{
		if(gnutls_record_send (*(td->tls_session), answer, msglen) < 0)
		{
			syslog(LOG_ERR, "gnutls_record_send error");
			return APR_EGENERAL;
		}
	}
	return APR_SUCCESS;
}
예제 #14
0
파일: gnutls.c 프로젝트: Macs/NeoIRCd
static ssize_t
rb_ssl_read_or_write(int r_or_w, rb_fde_t *F, void *rbuf, const void *wbuf, size_t count)
{
	ssize_t ret;
	gnutls_session_t *ssl = F->ssl;

	if(r_or_w == 0)
		ret = gnutls_record_recv(*ssl, rbuf, count);
	else
		ret = gnutls_record_send(*ssl, wbuf, count);

	if(ret < 0)
	{
		switch (ret)
		{
		case GNUTLS_E_AGAIN:
		case GNUTLS_E_INTERRUPTED:
			if(rb_ignore_errno(errno))
			{
				if(gnutls_record_get_direction(*ssl) == 0)
					return RB_RW_SSL_NEED_READ;
				else
					return RB_RW_SSL_NEED_WRITE;
				break;
			}
		default:
			F->ssl_errno = ret;
			errno = EIO;
			return RB_RW_IO_ERROR;
		}
	}
	return ret;
}
int tls_connection_encrypt(void *ssl_ctx, struct tls_connection *conn,
                           const u8 *in_data, size_t in_len,
                           u8 *out_data, size_t out_len)
{
        ssize_t res;

#ifdef GNUTLS_IA
        if (conn->tls_ia)
                res = gnutls_ia_send(conn->session, (char *) in_data, in_len);
        else
#endif /* GNUTLS_IA */
        res = gnutls_record_send(conn->session, in_data, in_len);
        if (res < 0) {
                wpa_printf(MSG_INFO, "%s: Encryption failed: %s",
                           __func__, gnutls_strerror(res));
                return -1;
        }
        if (conn->push_buf == NULL)
                return -1;
        if (conn->push_buf_len < out_len)
                out_len = conn->push_buf_len;
        else if (conn->push_buf_len > out_len) {
                wpa_printf(MSG_INFO, "GnuTLS: Not enough buffer space for "
                           "encrypted message (in_len=%lu push_buf_len=%lu "
                           "out_len=%lu",
                           (unsigned long) in_len,
                           (unsigned long) conn->push_buf_len,
                           (unsigned long) out_len);
        }
        os_memcpy(out_data, conn->push_buf, out_len);
        os_free(conn->push_buf);
        conn->push_buf = NULL;
        conn->push_buf_len = 0;
        return out_len;
}
예제 #16
0
static size_t
ssl_gnutls_write(PurpleSslConnection *gsc, const void *data, size_t len)
{
	PurpleSslGnutlsData *gnutls_data = PURPLE_SSL_GNUTLS_DATA(gsc);
	ssize_t s = 0;

	/* XXX: when will gnutls_data be NULL? */
	if(gnutls_data)
		s = gnutls_record_send(gnutls_data->session, data, len);

	if(s == GNUTLS_E_AGAIN || s == GNUTLS_E_INTERRUPTED) {
		s = -1;
		errno = EAGAIN;
	} else if(s < 0) {
		purple_debug_error("gnutls", "send failed: %s\n",
				gnutls_strerror(s));
		s = -1;
		/*
		 * TODO: Set errno to something more appropriate.  Or even
		 *       better: allow ssl plugins to keep track of their
		 *       own error message, then add a new ssl_ops function
		 *       that returns the error message.
		 */
		errno = EIO;
	}

	return s;
}
예제 #17
0
파일: gnutls.cpp 프로젝트: UIKit0/tntnet
  int GnuTlsStream::sslWrite(const char* buffer, int bufsize) const
  {
    int ret;

    fdInfo.timeout = getTimeout();

    // non-blocking/with timeout

    while (true)
    {
      log_debug("gnutls_record_send");
      ret = gnutls_record_send(session, buffer, bufsize);
      log_debug("gnutls_record_send => " << ret);

      if (ret > 0)
        break;

      if (ret == GNUTLS_E_AGAIN)
        throw cxxtools::IOTimeout();

      if (ret != GNUTLS_E_INTERRUPTED)
        throw GnuTlsException("gnutls_record_send", ret);
    }

    return ret;
  }
예제 #18
0
void server(int sock)
{ 
	gnutls_session_t s = session(sock, 1);
	int err;
	time_t started = time(0);

	write(sock, &sock, 1);

	setup_killtimer();

	do {
		await(sock);
		err = log(gnutls_handshake(s));
		reset_killtimer();
	} while (err != 0 && !gnutls_error_is_fatal(err));
	log_error(err, started);

	for (;;) {
		char buffer[8192];
		int len;
		do {
			await(sock);
			len = gnutls_record_recv(s, buffer, sizeof(buffer));
			reset_killtimer();
		} while (len < 0 && !gnutls_error_is_fatal(len));
		log_error(len, started);

		gnutls_record_send(s, buffer, len);
		exit(0);
	}
}
예제 #19
0
파일: ssl_gnutls.c 프로젝트: darnir/neomutt
/**
 * tls_socket_write - Write data to a TLS socket - Implements Connection::conn_write()
 */
static int tls_socket_write(struct Connection *conn, const char *buf, size_t count)
{
  struct TlsSockData *data = conn->sockdata;
  size_t sent = 0;

  if (!data)
  {
    mutt_error(_("Error: no TLS socket open"));
    return -1;
  }

  do
  {
    int ret;
    do
    {
      ret = gnutls_record_send(data->state, buf + sent, count - sent);
    } while ((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED));

    if (ret < 0)
    {
      mutt_error("tls_socket_write (%s)", gnutls_strerror(ret));
      return -1;
    }

    sent += ret;
  } while (sent < count);

  return sent;
}
예제 #20
0
/**
 * gnutls_record_uncork:
 * @session: is a #gnutls_session_t structure.
 * @flags: Could be zero or %GNUTLS_RECORD_WAIT
 *
 * This resets the effect of gnutls_record_cork(), and flushes any pending
 * data. If the %GNUTLS_RECORD_WAIT flag is specified then this
 * function will block until the data is sent or a fatal error
 * occurs (i.e., the function will retry on %GNUTLS_E_AGAIN and
 * %GNUTLS_E_INTERRUPTED).
 *
 * If the flag %GNUTLS_RECORD_WAIT is not specified and the function
 * is interrupted then the %GNUTLS_E_AGAIN or %GNUTLS_E_INTERRUPTED
 * errors will be returned. To obtain the data left in the corked
 * buffer use gnutls_record_check_corked().
 *
 * Returns: On success the number of transmitted data is returned, or 
 * otherwise a negative error code. 
 *
 * Since: 3.1.9
 **/
int gnutls_record_uncork(gnutls_session_t session, unsigned int flags)
{
	int ret;
	ssize_t total = 0;

	if (session->internals.record_flush_mode == RECORD_FLUSH)
		return 0;	/* nothing to be done */

	session->internals.record_flush_mode = RECORD_FLUSH;

	while (session->internals.record_presend_buffer.length > 0) {
		if (flags == GNUTLS_RECORD_WAIT) {
			do {
				ret =
				    gnutls_record_send(session,
						       session->internals.
						       record_presend_buffer.
						       data,
						       session->internals.
						       record_presend_buffer.
						       length);
			}
			while (ret < 0 && (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED));
		} else {
			ret =
			    gnutls_record_send(session,
					       session->internals.
					       record_presend_buffer.data,
					       session->internals.
					       record_presend_buffer.
					       length);
		}
		if (ret < 0)
			goto fail;

		session->internals.record_presend_buffer.data += ret;
		session->internals.record_presend_buffer.length -= ret;
		total += ret;
	}

	return total;

      fail:
	session->internals.record_flush_mode = RECORD_CORKED;
	return ret;
}
예제 #21
0
int tls_write(tls_t *tls, const void * const buff, const size_t len)
{
    int ret;

    ret = gnutls_record_send(tls->session, buff, len);

    return ret;
}
예제 #22
0
static int send_command(load_reference lLoad, socket_reference rReference,
remote_connection sSocket, const char *dData, ssize_t sSize)
{
	gnutls_transport_set_ptr(get_session(rReference),
	  (gnutls_transport_ptr_t) sSocket);
	int outcome = gnutls_record_send(get_session(rReference), dData, sSize);

	return outcome;
}
예제 #23
0
int tls_write(tls_t *tls, const void * const buff, const size_t len)
{
    int ret;

    ret = gnutls_record_send(tls->session, buff, len);
    tls->lasterror = ret < 0 ? ret : 0;

    return ret;
}
예제 #24
0
파일: gnutls.c 프로젝트: forthyen/SDesk
/*****************************************************************************
 * tls_Send:
 *****************************************************************************
 * Sends data through a TLS session.
 *****************************************************************************/
static int
gnutls_Send( tls_session_t *p_session, const char *buf, int i_length )
{
    int val;

    val = gnutls_record_send( *(gnutls_session *)(p_session->p_sys),
                              buf, i_length );
    return val < 0 ? -1 : val;
}
예제 #25
0
파일: TLSSocket.cpp 프로젝트: burner/vmime
void TLSSocket::sendRaw(const char* buffer, const size_type count)
{
	gnutls_record_send
		(*m_session->m_gnutlsSession,
		 buffer, static_cast <size_t>(count));

	if (m_ex)
		internalThrow();
}
예제 #26
0
/* Ugly, sending could fail and  other horrible things may happen. */
int smtp_quit(gnutls_session_t session) {
	char buffer[] = "QUIT\n";
	int sent = GNUTLS_E_AGAIN;
	sent = gnutls_record_send(session, buffer, sizeof(buffer));
	
	ssl_smtp_expect(session, "221 ");

	/* TODO: Better (read: some) error handling. */
	return 0;
}
예제 #27
0
static int tls_write(URLContext *h, const uint8_t *buf, int size)
{
    TLSContext *c = h->priv_data;
    int ret = gnutls_record_send(c->session, buf, size);
    if (ret > 0)
        return ret;
    if (ret == 0)
        return AVERROR_EOF;
    return print_tls_error(h, ret);
}
예제 #28
0
    bool mrutils::TLSServer::send(const char * msg, int len) {
        if (!connected_) return false;
        if (len == 0) len = strlen(msg);

        mrutils::mutexAcquire(windowsMutex);
            int ret = gnutls_record_send (session, msg, len);
        mrutils::mutexRelease(windowsMutex);

        return (ret == len);
    }
예제 #29
0
gint
_lm_ssl_send (LmSSL *ssl, const gchar *str, gint len)
{
    gint bytes_written;

    bytes_written = gnutls_record_send (ssl->gnutls_session, str, len);

    while (bytes_written < 0) {
        if (bytes_written != GNUTLS_E_INTERRUPTED &&
            bytes_written != GNUTLS_E_AGAIN) {
            return -1;
        }

        bytes_written = gnutls_record_send (ssl->gnutls_session,
                                            str, len);
    }

    return bytes_written;
}
예제 #30
0
ssize_t TCPStream::send(const char* buffer, size_t len)
{
    if(secure) {
        return gnutls_record_send(*m_session, buffer, len);
    }
    else {
        return write(m_sd, buffer, len);
    }

}