Beispiel #1
0
int	MaOpenSslSocket::write(char *buf, int len)
{
	int		rc, written, totalWritten;

	if (bio == 0 || ssl == 0 || len <= 0) {
		return -1;
	}

	BIO_clear_retry_flags(bio);

	totalWritten = 0;

	do {
		written = BIO_write(bio, buf, len);

		mprLog(7, "written %d, len %d\n", written, len);

		if (written >= 0) {
			do {
				rc = BIO_flush(bio);
				mprLog(7, "BIO_flush rc %d\n", rc);
				if (rc > 0) {
					//	Success
					break;
				}
				//
				//	Nap to prevent busy waiting.
				//
				mprSleep(10);
			} while (rc <= 0 && BIO_should_retry(bio));

			totalWritten += written;
			buf += written;
			len -= written;
		}

		mprLog(7, "write: len %d, written %d, total %d, should_retry %d\n",
			len, written, totalWritten, BIO_should_retry(bio));

		/*
 		 *	If written is < 0 and an error occurred, then BIO_should_retry
 		 *	will return false.
		 */
	} while (len > 0 && (written > 0 || BIO_should_retry(bio)));

	if (totalWritten <= 0 && BIO_should_retry(bio) == 0) {
		mprLog(7, "connection closed\n");
		/* 
		 *	If totalWritten is not Zero, then we don't return an Error.
		 * 	Next time this function is called, it will return an Error.
		 */
		return -1; // return Error ( connection closed )
	}
	return totalWritten;
}
Beispiel #2
0
int	MaOpenSslSocket::read(char *buf, int len)
{
	int		rc;

	if (bio == 0 || ssl == 0) {
		return -1;
	}

	rc = BIO_read(bio, buf, len);

#if DEBUG
	if (rc > 0 && !connTraced) {
		X509_NAME	*xSubject;
		X509		*cert;
		char		subject[260], issuer[260], peer[260];

		mprLog(4, "%d: SSL Connected using: \"%s\"\n", 
			sock, SSL_get_cipher(ssl));

		cert = SSL_get_peer_certificate(ssl);
		if (cert == 0) {
			mprLog(4, "%d: SSL Details: client supplied no certificate\n", 
				sock);
		} else {
			xSubject = X509_get_subject_name(cert);
			X509_NAME_oneline(xSubject, subject, sizeof(subject) -1);
			X509_NAME_oneline(X509_get_issuer_name(cert), issuer, 
				sizeof(issuer) -1);
			X509_NAME_get_text_by_NID(xSubject, NID_commonName, peer, 
				sizeof(peer) - 1);
			mprLog(4, "%d: SSL Subject %s\n", sock, subject);
			mprLog(4, "%d: SSL Issuer: %s\n", sock, issuer);
			mprLog(4, "%d: SSL Peer: %s\n", sock, peer);
			X509_free(cert);
		}
		connTraced = 1;
	}
#endif

	if (rc > 0) {
		return rc;

	} else if (rc == 0) {
		if (BIO_should_retry(bio)) {
			return 0;
		}
		flags |= MPR_SOCKET_EOF;
		return 0;
	}
	if (BIO_should_retry(bio)) {
		return 0;
	}
	return rc;
}
Beispiel #3
0
static int ok_write(BIO *b, const char *in, int inl)
{
    int ret = 0, n, i;
    BIO_OK_CTX *ctx;

    if (inl <= 0)
        return inl;

    ctx = (BIO_OK_CTX *)b->ptr;
    ret = inl;

    if ((ctx == NULL) || (b->next_bio == NULL) || (b->init == 0))
        return (0);

    if (ctx->sigio)
        sig_out(b);

    do {
        BIO_clear_retry_flags(b);
        n = ctx->buf_len - ctx->buf_off;
        while (ctx->blockout && n > 0) {
            i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
            if (i <= 0) {
                BIO_copy_next_retry(b);
                if (!BIO_should_retry(b))
                    ctx->cont = 0;
                return (i);
            }
            ctx->buf_off += i;
            n -= i;
        }

        /* at this point all pending data has been written */
        ctx->blockout = 0;
        if (ctx->buf_len == ctx->buf_off) {
            ctx->buf_len = OK_BLOCK_BLOCK;
            ctx->buf_off = 0;
        }

        if ((in == NULL) || (inl <= 0))
            return (0);

        n = (inl + ctx->buf_len > OK_BLOCK_SIZE + OK_BLOCK_BLOCK) ?
            (int)(OK_BLOCK_SIZE + OK_BLOCK_BLOCK - ctx->buf_len) : inl;

        memcpy((unsigned char *)(&(ctx->buf[ctx->buf_len])),
               (unsigned char *)in, n);
        ctx->buf_len += n;
        inl -= n;
        in += n;

        if (ctx->buf_len >= OK_BLOCK_SIZE + OK_BLOCK_BLOCK) {
            block_out(b);
        }
    } while (inl > 0);

    BIO_clear_retry_flags(b);
    BIO_copy_next_retry(b);
    return (ret);
}
Beispiel #4
0
unsigned char *Client::encode64(std::string data, int *lenoutput){
	const char *c_data = data.c_str();
	unsigned char *u_data = (unsigned char *) c_data;

	int len = data.size();
	
	BIO *b64, *bmem;
	b64 = BIO_new(BIO_f_base64());
	BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
	bmem = BIO_new(BIO_s_mem());
	BIO_push(b64, bmem);

	bool done = false;
	int res = 0;

	while(!done){
		res = BIO_write(b64, u_data, len);
		if(res <= 0){
			if(BIO_should_retry(b64))
				continue;
			else
				return NULL;
		}
		else
			done = true;
	}
	
	BIO_flush(b64);
	
	unsigned char *output;
	*lenoutput = BIO_get_mem_data(bmem, &output);
	
	return output;	
		
}
Beispiel #5
0
OCSP_RESPONSE *OCSP_sendreq_bio (BIO * b, char *path, OCSP_REQUEST * req)
{
    OCSP_RESPONSE *resp = NULL;

    OCSP_REQ_CTX *ctx;

    int rv;

    ctx = OCSP_sendreq_new (b, path, req, -1);

    if (!ctx)
        return NULL;

    do
    {
        rv = OCSP_sendreq_nbio (&resp, ctx);
    }
    while ((rv == -1) && BIO_should_retry (b));

    OCSP_REQ_CTX_free (ctx);

    if (rv)
        return resp;

    return NULL;
}
Beispiel #6
0
int tls_write_all(rdpTls* tls, const BYTE* data, int length)
{
	int status;
	int offset = 0;
	BIO* bio = tls->bio;

	while (offset < length)
	{
		status = BIO_write(bio, &data[offset], length - offset);

		if (status > 0)
		{
			offset += status;
		}
		else
		{
			if (!BIO_should_retry(bio))
				return -1;

			if (BIO_write_blocked(bio))
				status = BIO_wait_write(bio, 100);
			else if (BIO_read_blocked(bio))
				status = BIO_wait_read(bio, 100);
			else
				USleep(100);

			if (status < 0)
				return -1;
		}
	}

	return length;
}
static enum pbpal_resolv_n_connect_result resolv_and_connect_wout_SSL(pubnub_t *pb)
{
    PUBNUB_LOG_TRACE("resolv_and_connect_wout_SSL\n");
    if (NULL == pb->pal.socket) {
        char const*origin = PUBNUB_ORIGIN_SETTABLE ? pb->origin : PUBNUB_ORIGIN;
        PUBNUB_LOG_TRACE("pb=%p: Don't have BIO\n", pb);
        pb->pal.socket = BIO_new_connect((char*)origin);
    }
    if (NULL == pb->pal.socket) {
        return pbpal_resolv_resource_failure;
    }
    BIO_set_conn_port(pb->pal.socket, "http");

    BIO_set_nbio(pb->pal.socket, !pb->options.use_blocking_io);

    WATCH_ENUM(pb->options.use_blocking_io);
    if (BIO_do_connect(pb->pal.socket) <= 0) {
        if (BIO_should_retry(pb->pal.socket)) {
            return pbpal_connect_wouldblock;
        }
        ERR_print_errors_cb(print_to_pubnub_log, NULL);
        PUBNUB_LOG_ERROR("BIO_do_connect failed\n");
        return pbpal_connect_failed;
    }

    PUBNUB_LOG_TRACE("pb=%p: BIO connected\n", pb);
    {
        int fd = BIO_get_fd(pb->pal.socket, NULL);
        socket_set_rcv_timeout(fd, pb->transaction_timeout_ms);
    }

    return pbpal_connect_success;
}
Beispiel #8
0
static LUA_FUNCTION(openssl_bio_puts)
{
  BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio");
  const char* s = luaL_checkstring(L, 2);
  int ret = 1;
  int len = BIO_puts(bio, s);

  if (len > 0)
  {
    lua_pushinteger(L, len);
    ret = 1;
  }
  else if (BIO_should_retry(bio))
  {
    lua_pushinteger(L, 0);
    ret = 1;
  }
  else
  {
    lua_pushnil(L);
    lua_pushinteger(L, len);
    ret = 2;
  };
  return ret;
}
Beispiel #9
0
static int transport_bio_buffered_read(BIO* bio, char* buf, int size)
{
	int status;
	rdpTcp* tcp = (rdpTcp*) bio->ptr;

	tcp->readBlocked = FALSE;
	BIO_clear_flags(bio, BIO_FLAGS_READ);

	status = BIO_read(bio->next_bio, buf, size);

	if (status <= 0)
	{
		if (!BIO_should_retry(bio->next_bio))
		{
			BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY);
			status = -1;
			goto out;
		}

		BIO_set_flags(bio, BIO_FLAGS_SHOULD_RETRY);

		if (BIO_should_read(bio->next_bio))
		{
			BIO_set_flags(bio, BIO_FLAGS_READ);
			tcp->readBlocked = TRUE;
			goto out;
		}
	}

out:
	return status;
}
Beispiel #10
0
int write_to_BIO( BIO *bio, char *out, int len ) 
{
    int total, written;
    int errcode;

    /* This loop writes the data to the file. It checks for errors as if the
     underlying file were non-blocking */
    for (total = 0; total < len; total += written) {
        if ((written = BIO_write (bio, out + total, len - total)) <= 0) {
            if (BIO_should_retry (bio)) {
                written = 0;
            }
            else {
                /* return the error */
                errcode = ERR_get_error();
                /* FIXME - do something with errcode? */
                return written;
            }
        }
    }

    /* Ensure all of our data is pushed all the way out to the destination */
    BIO_flush( bio );

    return total;
}
Beispiel #11
0
int       
__bro_openssl_read(BroConn *bc, uchar *buf, uint buf_size)
{
  int n;

  D_ENTER;
  
  /* It's important here to use <= for comparison, since, as the
   * invaluable O'Reilly OpenSSL book reports, "for each of the four
   * reading and writing functions, a 0 or -1 return value may or may
   * not necessarily indicate that an error has occurred." This may or
   * may not necessarily be indicative of the incredible PITA that
   * OpenSSL is. --cpk
   */
  if ( (n = BIO_read(bc->bio, buf, buf_size)) <= 0)
    {
      if (BIO_should_retry(bc->bio))
	D_RETURN_(0);
      
      __bro_openssl_shutdown(bc);
      D(("Connection closed, BIO_read() returned %i.\n", n));      
      print_errors();
      D_RETURN_(-1);
    }
    
  D_RETURN_(n);
}
Beispiel #12
0
/* Returns the amount written. */
static int bio_bucket_write(BIO *bio, const char *in, int inl)
{
    serf_ssl_context_t *ctx = bio->ptr;
    serf_bucket_t *tmp;

#ifdef SSL_VERBOSE
    printf("bio_bucket_write called for %d bytes\n", inl);
#endif
    if (ctx->encrypt.status == SERF_ERROR_WAIT_CONN
        && !BIO_should_read(ctx->bio)) {
#ifdef SSL_VERBOSE
        printf("bio_bucket_write waiting: (%d %d %d)\n",
           BIO_should_retry(ctx->bio), BIO_should_read(ctx->bio),
           BIO_get_retry_flags(ctx->bio));
#endif
        /* Falling back... */
        ctx->encrypt.exhausted_reset = 1;
        BIO_clear_retry_flags(bio);
    }

    tmp = serf_bucket_simple_copy_create(in, inl,
                                         ctx->encrypt.pending->allocator);

    serf_bucket_aggregate_append(ctx->encrypt.pending, tmp);

    return inl;
}
Beispiel #13
0
static LUA_FUNCTION(openssl_bio_gets)
{
  BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio");
  int len = luaL_optint(L, 2, BIO_pending(bio));
  char* buf;
  int ret = 1;
  len = len > 0 ? len : 1024;

  buf = malloc(len);
  len = BIO_gets(bio, buf, len);
  if (len > 0)
  {
    lua_pushlstring(L, buf, len);
    ret = 1;
  }
  else if (BIO_should_retry(bio))
  {
    lua_pushstring(L, "");
    ret = 1;
  }
  else
  {
    lua_pushnil(L);
    lua_pushinteger(L, len);
    ret = 2;
  };
  free(buf);
  return ret;
}
Beispiel #14
0
/**
 * Receive data package though the ssl connection
 * @param ssl ssl connection
 * @param buffer array to hold the data
 * @param len size of the data container
 * @param timeout Seconds to wait for data to be available
 * @return number of bytes transmitted, -1 in case of an error
 */
int recv_ssl_socket(ssl_connection *ssl, void *buffer, int len, int timeout) {

#ifdef HAVE_OPENSSL
    int n= 0;

    ASSERT(ssl);

    do {
        n= SSL_read(ssl->handler, buffer, len);
    } while(n <= 0 &&
            BIO_should_retry(ssl->socket_bio) &&
            can_read(ssl->socket, timeout));

    if(n <= 0) {
        return -1;
    }

    return n;

#else

    return -1;

#endif

}
Beispiel #15
0
/**
 * Read a from a stream and handle restarts if nessecary
 */
ssize_t read_from_stream(BIO* bio, char* buffer, ssize_t length) {

    ssize_t r = -1;

    while (r < 0) {

        r = BIO_read(bio, buffer, length);
        if (r == 0) {

            print_ssl_error("Reached the end of the data stream.\n", stdout);
            continue;

        } else if (r < 0) {

            if (!BIO_should_retry(bio)) {

                print_ssl_error("BIO_read should retry test failed.\n", stdout);
                continue;
            }

            /* It would be prudent to check the reason for the retry and handle
             * it appropriately here */
        }

    };

    return r;
}
Beispiel #16
0
void SSLClient::process(bool bInRead)
{
    for (;;){
        switch (state){
        case SSLWrite:
            write();
            break;
        case SSLConnect:
            connect();
            break;
        case SSLAccept:
            accept();
            break;
        case SSLShutdown:
            shutdown();
            break;
        case SSLConnected:
            if (!bInRead && (SSL_pending(pSSL) > 0))
                notify->read_ready();
            break;
        }
        char b[2048];
        int i = BIO_read(wBIO, b, sizeof(b));
        if (i == 0) return;
        if (i > 0){
            sock->write(b, i);
            continue;
        }
        if (i < 0){
            if (!BIO_should_retry(wBIO))
                notify->error_state(I18N_NOOP("SSL write error"));
            return;
        }
    }
}
Beispiel #17
0
static int transport_bio_buffered_read(BIO* bio, char* buf, int size)
{
	int status;
	WINPR_BIO_BUFFERED_SOCKET* ptr = (WINPR_BIO_BUFFERED_SOCKET*) BIO_get_data(bio);
	BIO* next_bio = BIO_next(bio);

	ptr->readBlocked = FALSE;
	BIO_clear_flags(bio, BIO_FLAGS_READ);

	status = BIO_read(next_bio, buf, size);

	if (status <= 0)
	{
		if (!BIO_should_retry(next_bio))
		{
			BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY);
			goto out;
		}

		BIO_set_flags(bio, BIO_FLAGS_SHOULD_RETRY);

		if (BIO_should_read(next_bio))
		{
			BIO_set_flags(bio, BIO_FLAGS_READ);
			ptr->readBlocked = TRUE;
			goto out;
		}
	}

out:
	return status;
}
Beispiel #18
0
static LUA_FUNCTION(openssl_bio_write)
{
  BIO* bio = CHECK_OBJECT(1, BIO, "openssl.bio");
  size_t size = 0;
  const char* d = luaL_checklstring(L, 2, &size);
  int ret = 1;
  int len = luaL_optint(L, 3, size);

  len = BIO_write(bio, d, len);
  if (len > 0)
  {
    lua_pushinteger(L, len);
    ret = 1;
  }
  else if (BIO_should_retry(bio))
  {
    lua_pushinteger(L, 0);
    ret = 1;
  }
  else
  {
    lua_pushnil(L);
    lua_pushinteger(L, len);
    ret = 2;
  };
  return ret;
}
Beispiel #19
0
static int transport_bio_buffered_write(BIO* bio, const char* buf, int num)
{
	int i, ret;
	int status;
	int nchunks;
	int committedBytes;
	DataChunk chunks[2];
	WINPR_BIO_BUFFERED_SOCKET* ptr = (WINPR_BIO_BUFFERED_SOCKET*) bio->ptr;

	ret = num;
	ptr->writeBlocked = FALSE;
	BIO_clear_flags(bio, BIO_FLAGS_WRITE);

	/* we directly append extra bytes in the xmit buffer, this could be prevented
	 * but for now it makes the code more simple.
	 */
	if (buf && num && !ringbuffer_write(&ptr->xmitBuffer, (const BYTE*) buf, num))
	{
		WLog_ERR(TAG, "an error occured when writing (num: %d)", num);
		return -1;
	}

	committedBytes = 0;
	nchunks = ringbuffer_peek(&ptr->xmitBuffer, chunks, ringbuffer_used(&ptr->xmitBuffer));

	for (i = 0; i < nchunks; i++)
	{
		while (chunks[i].size)
		{
			status = BIO_write(bio->next_bio, chunks[i].data, chunks[i].size);

			if (status <= 0)
			{
				if (!BIO_should_retry(bio->next_bio))
				{
					BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY);
					ret = -1; /* fatal error */
					goto out;
				}

				if (BIO_should_write(bio->next_bio))
				{
					BIO_set_flags(bio, BIO_FLAGS_WRITE);
					ptr->writeBlocked = TRUE;
					goto out; /* EWOULDBLOCK */
				}
			}

			committedBytes += status;
			chunks[i].size -= status;
			chunks[i].data += status;
		}
	}

out:
	ringbuffer_commit_read_bytes(&ptr->xmitBuffer, committedBytes);

	return ret;
}
Beispiel #20
0
/**
 * Embeds a socket in a ssl connection.
 * @param socket the socket to be used.
 * @return The ssl connection or NULL if an error occured.
 */
int embed_ssl_socket(ssl_connection *ssl, int socket) {
  int ssl_error;
  time_t ssl_time;
  
  if (!ssl)
    return FALSE;
  
  if (!ssl_initialized)
    start_ssl();

  if (socket >= 0) {
    ssl->socket = socket;
  } else {
    LogError("%s: Socket error!\n", prog);
    goto sslerror;
  }

  if ((ssl->handler = SSL_new (ssl->ctx)) == NULL) {
    LogError("%s: Cannot initialize the SSL handler -- %s\n", prog, SSLERROR);
    goto sslerror;
  }

  set_noblock(ssl->socket);

  if ((ssl->socket_bio = BIO_new_socket(ssl->socket, BIO_NOCLOSE)) == NULL) {
    LogError("%s: Cannot generate IO buffer -- %s\n", prog, SSLERROR);
    goto sslerror;
  }

  SSL_set_bio(ssl->handler, ssl->socket_bio, ssl->socket_bio);
  ssl_time = time(NULL);

  while ((ssl_error = SSL_connect (ssl->handler)) < 0) {
    if ((time(NULL) - ssl_time) > SSL_TIMEOUT) {
      LogError("%s: SSL service timeout!\n", prog);
      goto sslerror;
    }

    if (!handle_error(ssl_error, ssl))
      goto sslerror;

    if (!BIO_should_retry(ssl->socket_bio))
      goto sslerror;
  }

  ssl->cipher = (char *) SSL_get_cipher(ssl->handler);

  if (! update_ssl_cert_data(ssl)) {
    LogError("%s: Cannot get the SSL server certificate!\n", prog);
    goto sslerror;
  }

  return TRUE;

sslerror:
  cleanup_ssl_socket(ssl);
  return FALSE;
} 
Beispiel #21
0
static BOOL rdg_process_control_packet(rdpRdg* rdg, int type, size_t packetLength)
{
	wStream* s = NULL;
	size_t readCount = 0;
	int status;
	size_t payloadSize = packetLength - sizeof(RdgPacketHeader);

	if (payloadSize)
	{
		s = Stream_New(NULL, payloadSize);

		if (!s)
			return FALSE;

		while (readCount < payloadSize)
		{
			status = BIO_read(rdg->tlsOut->bio, Stream_Pointer(s), sizeof(RdgPacketHeader) - readCount);

			if (status <= 0)
			{
				if (!BIO_should_retry(rdg->tlsOut->bio))
				{
					Stream_Free(s, TRUE);
					return FALSE;
				}

				continue;
			}

			Stream_Seek(s, status);
			readCount += status;
		}
	}

	switch (type)
	{
		case PKT_TYPE_CLOSE_CHANNEL:
			EnterCriticalSection(&rdg->writeSection);
			status = rdg_process_close_packet(rdg);
			LeaveCriticalSection(&rdg->writeSection);
			break;

		case PKT_TYPE_KEEPALIVE:
			EnterCriticalSection(&rdg->writeSection);
			status = rdg_process_keep_alive_packet(rdg);
			LeaveCriticalSection(&rdg->writeSection);
			break;

		default:
			status = rdg_process_unknown_packet(rdg, type);
			break;
	}

	Stream_Free(s, TRUE);
	return status;
}
Beispiel #22
0
static int transport_bio_buffered_write(BIO* bio, const char* buf, int num)
{
	int status, ret;
	rdpTcp* tcp = (rdpTcp*) bio->ptr;
	int nchunks, committedBytes, i;
	DataChunk chunks[2];

	ret = num;
	tcp->writeBlocked = FALSE;
	BIO_clear_flags(bio, BIO_FLAGS_WRITE);

	/* we directly append extra bytes in the xmit buffer, this could be prevented
	 * but for now it makes the code more simple.
	 */
	if (buf && num && !ringbuffer_write(&tcp->xmitBuffer, (const BYTE*) buf, num))
	{
		fprintf(stderr, "%s: an error occured when writing(toWrite=%d)\n", __FUNCTION__, num);
		return -1;
	}

	committedBytes = 0;
	nchunks = ringbuffer_peek(&tcp->xmitBuffer, chunks, ringbuffer_used(&tcp->xmitBuffer));

	for (i = 0; i < nchunks; i++)
	{
		while (chunks[i].size)
		{
			status = BIO_write(bio->next_bio, chunks[i].data, chunks[i].size);

			if (status <= 0)
			{
				if (!BIO_should_retry(bio->next_bio))
				{
					BIO_clear_flags(bio, BIO_FLAGS_SHOULD_RETRY);
					ret = -1; /* fatal error */
					goto out;
				}

				if (BIO_should_write(bio->next_bio))
				{
					BIO_set_flags(bio, BIO_FLAGS_WRITE);
					tcp->writeBlocked = TRUE;
					goto out; /* EWOULDBLOCK */
				}
			}

			committedBytes += status;
			chunks[i].size -= status;
			chunks[i].data += status;
		}
	}

out:
	ringbuffer_commit_read_bytes(&tcp->xmitBuffer, committedBytes);
	return ret;
}
Beispiel #23
0
/*
 * Read from an OpenSSL BIO in non-blocking mode.
 */
static int
bio_read (BIO *bio, struct buffer *buf, int maxlen, const char *desc)
{
  int i;
  int ret = 0;
  ASSERT (buf->len >= 0);
  if (buf->len)
    {
      ;
    }
  else
    {
      int len = buf_forward_capacity (buf);
      if (maxlen < len)
	len = maxlen;

      /*
       * BIO_read brackets most of the serious RSA
       * key negotiation number crunching.
       */
      i = BIO_read (bio, BPTR (buf), len);

      VALGRIND_MAKE_READABLE ((void *) &i, sizeof (i));

#ifdef BIO_DEBUG
      bio_debug_data ("read", bio, BPTR (buf), i, desc);
#endif
      if (i < 0)
	{
	  if (BIO_should_retry (bio))
	    {
	      ;
	    }
	  else
	    {
	      msg (D_TLS_ERRORS | M_SSL, "TLS_ERROR: BIO read %s error",
		   desc);
	      buf->len = 0;
	      ret = -1;
	      ERR_clear_error ();
	    }
	}
      else if (!i)
	{
	  buf->len = 0;
	}
      else
	{			/* successful read */
	  dmsg (D_HANDSHAKE_VERBOSE, "BIO read %s %d bytes", desc, i);
	  buf->len = i;
	  ret = 1;
	  VALGRIND_MAKE_READABLE ((void *) BPTR (buf), BLEN (buf));
	}
    }
  return ret;
}
Beispiel #24
0
const char *dbapi_lookup(const char *key) {
	long res = 1;
	SSL_CTX* ctx = NULL;
	BIO *web = NULL, *out = NULL;
	SSL *ssl = NULL;
	const SSL_METHOD* method;
	char *token, *tmpout, *buf;
	int hlen=0, len=0, maxlen=2048;
	(void)SSL_library_init();
	SSL_load_error_strings();
	OPENSSL_config(NULL);
	method = SSLv23_method(); if(method==NULL) return NULL;
	ctx = SSL_CTX_new(method); if(ctx==NULL) return NULL;
	SSL_CTX_set_verify_depth(ctx, 4);
	SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|SSL_OP_NO_TLSv1|
		SSL_OP_NO_COMPRESSION);
	web = BIO_new_ssl_connect(ctx); if(web==NULL) return NULL;
	res = BIO_set_conn_hostname(web, DB_API_SERVER); if(res!=1) return NULL;
	BIO_get_ssl(web, &ssl); if(ssl==NULL) return NULL;
	res = SSL_set_cipher_list(ssl, SECURE_CIPHER_LIST); if(res!=1) return NULL;
	res = SSL_set_tlsext_host_name(ssl, DB_API_HOST); if(res!=1) return NULL;
	out = BIO_new_fp(stdout, BIO_NOCLOSE); if(NULL==out) return NULL;
	res = BIO_do_connect(web); if(res!=1) return NULL;
	res = BIO_do_handshake(web); if(res!=1) return NULL;
	len=(60+strlen(key)+strlen(DB_API_HOST)+strlen(DB_API_AUTH));
	char *request=malloc(sizeof(char)*(len+1));
	snprintf(request,len,
		"GET %s HTTP/1.1\nHost: %s\nx-api-key: %s\nConnection: close\n\n",
		key, DB_API_HOST, DB_API_AUTH);
	request[len]='\0';
	BIO_puts(web, request);
	BIO_puts(out, "\n");
	buf = malloc(sizeof(char)*maxlen);
	do {
		char buff[1536] = {};
		len=BIO_read(web, buff, sizeof(buff));
		hlen+=len;
		if(hlen<maxlen&&len>0) strncat(buf,buff,len);
	} while (len>0 || BIO_should_retry(web));
	buf[maxlen]='\0';
	tmpout = malloc(sizeof(char)*(HASH_MAXLENGTH+1));
	token = strtok(buf, "\n");
	while (token) {
		snprintf(tmpout,HASH_MAXLENGTH,"%s",token);
		token = strtok(NULL, "\n");
	}
	tmpout[strlen(tmpout)]='\0';
	free(buf);
	free(request);
	if(out) BIO_free(out);
	if(web != NULL) BIO_free_all(web);
	if(NULL != ctx) SSL_CTX_free(ctx);
	return tmpout;
}
Beispiel #25
0
/**
 * Send data package though the ssl connection 
 * @param ssl ssl connection
 * @param buffer array containg the data
 * @param len size of the data container
 * @param timeout Seconds to wait for data to be written
 * @return number of bytes transmitted, -1 in case of an error
 */
int send_ssl_socket(ssl_connection *ssl, void *buffer, size_t len, int timeout) {
        int n = 0;
        
        ASSERT(ssl);
        
        do {
                n = SSL_write(ssl->handler, buffer, (int)len);
        } while (n <= 0 && BIO_should_retry(ssl->socket_bio) && can_write(ssl->socket, timeout));
        
        return (n > 0) ? n : -1;
}
Beispiel #26
0
/**
 * Receive data package though the ssl connection 
 * @param ssl ssl connection
 * @param buffer array to hold the data
 * @param len size of the data container
 * @param timeout Seconds to wait for data to be available
 * @return number of bytes transmitted, -1 in case of an error
 */
int recv_ssl_socket(ssl_connection *ssl, void *buffer, int len, int timeout) {
  int n = 0;

  ASSERT(ssl);

  do {
    n = SSL_read(ssl->handler, buffer, len);
  } while (n < 0 && BIO_should_retry(ssl->socket_bio) && can_read(ssl->socket, timeout));
  
  return (n >= 0) ? n : -1;
}
Beispiel #27
0
int transport_read_layer(rdpTransport* transport, BYTE* data, int bytes)
{
	int read = 0;
	int status = -1;

	if (!transport->frontBio)
	{
		transport->layer = TRANSPORT_LAYER_CLOSED;
		return -1;
	}

	while (read < bytes)
	{
		status = BIO_read(transport->frontBio, data + read, bytes - read);

		if (status <= 0)
		{
			if (!transport->frontBio || !BIO_should_retry(transport->frontBio))
			{
				/* something unexpected happened, let's close */
				if (!transport->frontBio)
				{
					WLog_Print(transport->log, WLOG_ERROR, "BIO_read: transport->frontBio null");
					return -1;
				}

				WLog_ERR_BIO(transport, "BIO_read", transport->frontBio);
				transport->layer = TRANSPORT_LAYER_CLOSED;
				return -1;
			}

			/* non blocking will survive a partial read */
			if (!transport->blocking)
				return read;

			/* blocking means that we can't continue until we have read the number of requested bytes */
			if (BIO_wait_read(transport->frontBio, 100) < 0)
			{
				WLog_ERR_BIO(transport, "BIO_wait_read", transport->frontBio);
				return -1;
			}

			continue;
		}

#ifdef HAVE_VALGRIND_MEMCHECK_H
		VALGRIND_MAKE_MEM_DEFINED(data + read, bytes - read);
#endif
		read += status;
	}

	return read;
}
Beispiel #28
0
BOOL CSSLSession::WriteRecvChannel(const BYTE* pData, int iLength)
{
	ASSERT(pData && iLength > 0);

	BOOL isOK = TRUE;
	int bytes = BIO_write(m_bioRecv, pData, iLength);

	if(bytes > 0)
		ASSERT(bytes == iLength);
	else if(!BIO_should_retry(m_bioRecv))
		isOK = FALSE;

	return isOK;
}
Beispiel #29
0
BIO *BIO_get_retry_BIO(BIO *bio, int *reason)
	{
	BIO *b,*last;

	b=last=bio;
	for (;;)
		{
		if (!BIO_should_retry(b)) break;
		last=b;
		b=b->next_bio;
		if (b == NULL) break;
		}
	if (reason != NULL) *reason=last->retry_reason;
	return(last);
	}
Beispiel #30
0
/*
 * Write to an OpenSSL BIO in non-blocking mode.
 */
static int
bio_write (BIO *bio, const uint8_t *data, int size, const char *desc)
{
  int i;
  int ret = 0;
  ASSERT (size >= 0);
  if (size)
    {
      /*
       * Free the L_TLS lock prior to calling BIO routines
       * so that foreground thread can still call
       * tls_pre_decrypt or tls_pre_encrypt,
       * allowing tunnel packet forwarding to continue.
       */
#ifdef BIO_DEBUG
      bio_debug_data ("write", bio, data, size, desc);
#endif
      i = BIO_write (bio, data, size);

      if (i < 0)
	{
	  if (BIO_should_retry (bio))
	    {
	      ;
	    }
	  else
	    {
	      msg (D_TLS_ERRORS | M_SSL, "TLS ERROR: BIO write %s error",
		   desc);
	      ret = -1;
	      ERR_clear_error ();
	    }
	}
      else if (i != size)
	{
	  msg (D_TLS_ERRORS | M_SSL,
	       "TLS ERROR: BIO write %s incomplete %d/%d", desc, i, size);
	  ret = -1;
	  ERR_clear_error ();
	}
      else
	{			/* successful write */
	  dmsg (D_HANDSHAKE_VERBOSE, "BIO write %s %d bytes", desc, i);
	  ret = 1;
	}
    }
  return ret;
}