Пример #1
0
bool TLS_SOCKET_CLASS::isPendingDataInNetworkInputBuffer()

//  DESCRIPTION     : Check for pending data.
//  PRECONDITIONS   :
//  POSTCONDITIONS  :
//  EXCEPTIONS      : 
//  NOTES           :
//<<===========================================================================
{
	/*int nrOfBytes;
	if(sslM_ptr != NULL)
		nrOfBytes = SSL_pending(sslM_ptr);
	if(nrOfBytes > 0) 
		return true;
	else
		return false;*/

	DWORD available;
	int handle = SSL_get_rfd(sslM_ptr);
	ioctlsocket(handle, FIONREAD, &available);
	if(available > 0) 
		return true;
	else
		return false;
}
Пример #2
0
gint ssl_peek(SSL *ssl, gchar *buf, gint len)
{
	gint err, ret;

	if (SSL_pending(ssl) == 0) {
		if (fd_check_io(SSL_get_rfd(ssl), G_IO_IN) < 0)
			return -1;
	}

	ret = SSL_peek(ssl, buf, len);

	switch ((err = SSL_get_error(ssl, ret))) {
	case SSL_ERROR_NONE:
		return ret;
	case SSL_ERROR_WANT_READ:
	case SSL_ERROR_WANT_WRITE:
		errno = EAGAIN;
		return -1;
	case SSL_ERROR_ZERO_RETURN:
		return 0;
	default:
		g_warning("SSL_peek() returned error %d, ret = %d\n", err, ret);
		if (ret == 0)
			return 0;
		return -1;
	}
}
Пример #3
0
/* Return the incoming_fd for a given stream */
int stream_get_incoming_fd(PTSTREAM *pts) {

	if (!pts->ssl)
		return pts->incoming_fd;
	else
#ifdef USE_SSL
		return SSL_get_rfd(pts->ssl);
#else
		return pts->incoming_fd;
#endif /* USE_SSL */
}
Пример #4
0
static int openssl_ssl_get(lua_State*L)
{
  SSL* s = CHECK_OBJECT(1, SSL, "openssl.ssl");
  int i;
  int top = lua_gettop(L);
  for (i = 2; i <= top; i++)
  {
    const char* what = luaL_checklstring(L, i, NULL);
    if (strcmp(what, "fd") == 0)
    {
      lua_pushinteger(L, SSL_get_fd(s));
    }
    else if (strcmp(what, "rfd") == 0)
    {
      lua_pushinteger(L, SSL_get_rfd(s));
    }
    else if (strcmp(what, "wfd") == 0)
    {
      lua_pushinteger(L, SSL_get_wfd(s));
    }
    else if (strcmp(what, "client_CA_list") == 0)
    {
      STACK_OF(X509_NAME)* sn = SSL_get_client_CA_list(s);
      PUSH_OBJECT(sn, "openssl.sk_x509_name");
    }
    else if (strcmp(what, "read_ahead") == 0)
    {
      lua_pushboolean(L, SSL_get_read_ahead(s));
    }
    else if (strcmp(what, "shared_ciphers") == 0)
    {
      char buf[LUAL_BUFFERSIZE] = {0};
      lua_pushstring(L, SSL_get_shared_ciphers(s, buf, sizeof(buf)));
    }
    else if (strcmp(what, "cipher_list") == 0)
    {
      //TODO FIX
      lua_pushstring(L, SSL_get_cipher_list(s, 0));
    }
    else if (strcmp(what, "verify_mode") == 0)
    {
      //FIX
      lua_pushinteger(L, SSL_get_verify_mode(s));
    }
    else if (strcmp(what, "verify_depth") == 0)
    {
      lua_pushinteger(L, SSL_get_verify_depth(s));
    }
    else if (strcmp(what, "state_string") == 0)
    {
      lua_pushstring(L, SSL_state_string(s));
    }
    else if (strcmp(what, "state_string_long") == 0)
    {
      lua_pushstring(L, SSL_state_string_long(s));
    }
    else if (strcmp(what, "rstate_string") == 0)
    {
      lua_pushstring(L, SSL_rstate_string(s));
    }
    else if (strcmp(what, "rstate_string_long") == 0)
    {
      lua_pushstring(L, SSL_rstate_string_long(s));
    }
    else if (strcmp(what, "version") == 0)
    {
      lua_pushstring(L, SSL_get_version(s));
    }
    else if (strcmp(what, "iversion") == 0)
    {
      lua_pushinteger(L, SSL_version(s));
    }
    else if (strcmp(what, "default_timeout") == 0)
    {
      lua_pushinteger(L, SSL_get_default_timeout(s));
    }
    else if (strcmp(what, "certificate") == 0)
    {
      X509* cert = SSL_get_certificate(s);
      PUSH_OBJECT(cert, "openssl.x509");
    }
    else if (strcmp(what, "verify_result") == 0)
    {
      long l = SSL_get_verify_result(s);
      lua_pushinteger(L, l);
    }
    else if (strcmp(what, "version") == 0)
    {
      lua_pushstring(L, SSL_get_version(s));
    }
    else if (strcmp(what, "state") == 0)
    {
      lua_pushinteger(L, SSL_state(s));
    }
    else if (strcmp(what, "hostname") == 0)
    {
      lua_pushstring(L, SSL_get_servername(s, TLSEXT_NAMETYPE_host_name));
    }
    else
      luaL_argerror(L, i, "can't understant");
  }
  return top - 1;
}
Пример #5
0
bool TLS_SOCKET_CLASS::writeBinary(const BYTE *buffer_ptr, UINT length)

//  DESCRIPTION     : Write given data to socket.
//  PRECONDITIONS   :
//  POSTCONDITIONS  :
//  EXCEPTIONS      : 
//  NOTES           :
//<<===========================================================================
{
	int written_bytes = 0;
	int readFileDesc;
	int writeFileDesc;
	struct fd_set readFds;
	struct fd_set writeFds;
	bool waitOnWrite;
	int timeoutRemaining; // the amount of time left in the timeout period
	struct timeval tv = {1, 0}; // always timeout in 1 second

	if (terminatingM)
	{
		if (loggerM_ptr) 
		{
			loggerM_ptr->text(LOG_ERROR, 1, "Secure Socket - In process of terminating.  Cannot write.");
		}

		// return - in process of termintating
		return false;
	}

	if (loggerM_ptr) 
	{
		loggerM_ptr->text(LOG_DEBUG, 1, "Secure Socket - tls::write(%d bytes)", length);
	}

	if (!connectedM) 
	{
		if (loggerM_ptr) 
		{
			loggerM_ptr->text(LOG_ERROR, 1, "Secure Socket - Not connected to peer - can't write data");
		}

		return false;
	}

	// get the file descriptors and set up the file descriptor sets for select()
	readFileDesc = SSL_get_rfd(sslM_ptr);
	if (readFileDesc == -1)
	{
		openSslError("getting read socket file descriptor");
		return false;
	}

	writeFileDesc = SSL_get_wfd(sslM_ptr);
	if (writeFileDesc == -1)
	{
		openSslError("getting write socket file descriptor");
		return false;
	}

	waitOnWrite = true;
	timeoutRemaining = socketTimeoutM;

	// write the buffer contents to socket
	while (written_bytes < (int) length)
	{
		int bytes;
		int sel;

		if (waitOnWrite)
		{
			FD_ZERO(&writeFds);
			FD_SET(writeFileDesc, &writeFds);

			// wait for something to write
			sel = select(writeFileDesc + 1, NULL, &writeFds, NULL, &tv);
		}
		else
		{
			FD_ZERO(&readFds);
			FD_SET(readFileDesc, &readFds);

			// wait for something to read
			sel = select(readFileDesc + 1, &readFds, NULL, NULL, &tv);
		}

		if (terminatingM)
		{
			return false;
		}

		waitOnWrite = true;

		if (sel == 1)
		{
			// data read to write (or possibly read - but use the same call)
			bytes = SSL_write(sslM_ptr, (char *)(buffer_ptr + written_bytes), (length - written_bytes));
			if (bytes > 0)
			{
				// wrote some data
				written_bytes += bytes;
				timeoutRemaining = socketTimeoutM; // reset the timeout
			}
			else if (bytes == 0)
			{
				// socket closed
				if (loggerM_ptr)
				{
					loggerM_ptr->text(LOG_ERROR, 1, "Secure Socket - Secure connection closed during socket write");
				}
				return false;
			}
			else
			{
				// operation did not complete, see what happened
				int err = SSL_get_error(sslM_ptr, bytes);
				if (err == SSL_ERROR_WANT_READ)
				{
					// need to wait for data to be available for reading, and then retry the same operation
					waitOnWrite = false;
					timeoutRemaining = socketTimeoutM; // reset the timeout
				}
				if (err == SSL_ERROR_WANT_WRITE)
				{
					// need to wait for the write file descriptor to be able to write and then try again
					timeoutRemaining = socketTimeoutM; // reset the timeout
				}
				else
				{
					// an error occured
					if ((err == SSL_ERROR_SYSCALL) && (ERR_peek_error() == 0) && (bytes == -1))
					{
						// an error in the system call occured
						openSslError("writing to secure socket");
						if (loggerM_ptr && (loggerM_ptr->getLogMask() & LOG_ERROR))
						{
							loggerM_ptr->text(LOG_NONE, 1, "    write() error code = %d", WSAGetLastError());
						}
					}
					else
					{
						openSslError("reading from secure socket");
					}
					return false;
				}
			}
		}
		else if (sel == 0)
		{
			// no data at the end of the timeout
			if (--timeoutRemaining > 0)
			{
				// still have time left on the timeout, go back and wait some more
			}
			else
			{
				// timeout expired
				if (loggerM_ptr)
				{
					loggerM_ptr->text(LOG_ERROR, 2, "Secure Socket - Connection timed-out while waiting to send data");
				}
				return false;
			}
		}
		else if (sel == SOCKET_ERROR)
		{
			// socket error
			if (loggerM_ptr)
			{
				loggerM_ptr->text(LOG_ERROR, 2, "Secure Socket - Error waiting to send data (error code %d)", WSAGetLastError());
			}
			return false;
		}
		else
		{
			// unknown error
			if (loggerM_ptr)
			{
				loggerM_ptr->text(LOG_ERROR, 2, "Secure Socket - Unknown error while waiting to send data (select returned %d)", sel);
			}
			return false;
		}
	}

	return (written_bytes == (int) length) ? true : false;
}
Пример #6
0
INT	TLS_SOCKET_CLASS::readBinary(BYTE *buffer_ptr, UINT length)

//  DESCRIPTION     : Read data from socket to given buffer.
//  PRECONDITIONS   :
//  POSTCONDITIONS  :
//  EXCEPTIONS      : 
//  NOTES           : Blocks until all of the requested data is read or a timeout occurs.
//<<===========================================================================
{
	int read_bytes = 0; // number of bytes read from the socket
	int readFileDesc;
	int writeFileDesc;
	struct fd_set readFds;
	struct fd_set writeFds;
	bool sslWaitOnRead; // indicates that the OpenSSL library is waiting for data to be sent on the socket
	bool sslWaitOnWrite; // indicates that the OpenSSL library is waiting to be able to write to the socket interface
	int timeoutRemaining; // the amount of time left in the timeout period
	struct timeval tv = {1, 0}; // always timeout in 1 second

	if (terminatingM)
	{
		if (loggerM_ptr) 
		{
			loggerM_ptr->text(LOG_ERROR, 1, "Secure Socket - In process of terminating.  Cannot read.");
		}

		// return - in process of termintating
		return -1;
	}

	if (loggerM_ptr) 
	{
		loggerM_ptr->text(LOG_DEBUG, 1, "Secure Socket - tls::read(%d bytes)", length);
	}

	if (!connectedM) 
	{
		if (loggerM_ptr) 
		{
			loggerM_ptr->text(LOG_ERROR, 1, "Secure Socket - Not connected to peer - can't read data");
		}

		return -1;
	}

	// get the file descriptors and set up the file descriptor sets for select()
	readFileDesc = SSL_get_rfd(sslM_ptr);
	if (readFileDesc == -1)
	{
		openSslError("getting read socket file descriptor");
		return -1;
	}

	writeFileDesc = SSL_get_wfd(sslM_ptr);
	if (writeFileDesc == -1)
	{
		openSslError("getting write socket file descriptor");
		return -1;
	}

	sslWaitOnRead = false;
	sslWaitOnWrite = false;
	timeoutRemaining = socketTimeoutM;

	// fill the buffer from the socket
	while (read_bytes < (int) length)
	{
		int bytes;
		int sel;

		if (sslWaitOnWrite)
		{
			FD_ZERO(&writeFds);
			FD_SET(writeFileDesc, &writeFds);

			// wait for the socket to be able to accept a write operation
			sel = select(writeFileDesc + 1, NULL, &writeFds, NULL, &tv);
		}
		else if (sslWaitOnRead || // OpenSSL asked us to wait
				(SSL_pending(sslM_ptr) == 0)) // there is no data in the SSL buffer
		{
			FD_ZERO(&readFds);
			FD_SET(readFileDesc, &readFds);

			// wait for something on the socket
			sel = select(readFileDesc + 1, &readFds, NULL, NULL, &tv);
		}
		else
		{
			// don't wait, there is data to be read from the SSL buffer
			sel = 1;
		}

		if (terminatingM)
		{
			return -1;
		}

		sslWaitOnRead = false;
		sslWaitOnWrite = false;

		if (sel == 1)
		{
			// data ready to be read (or possibly write - but use the same call)
			bytes = SSL_read(sslM_ptr, (char *)(buffer_ptr + read_bytes), (length - read_bytes));
			if (bytes > 0)
			{
				// read some data
				read_bytes += bytes;
				timeoutRemaining = socketTimeoutM; // reset the timeout
			}
			else if (bytes == 0)
			{
				// socket closed
				if (loggerM_ptr)
				{
					loggerM_ptr->text(LOG_ERROR, 1, "Secure Socket - Secure connection closed during socket read");
				}
				return -1;
			}
			else
			{
				// operation did not complete, see what happened
				int err = SSL_get_error(sslM_ptr, bytes);
				if (err == SSL_ERROR_WANT_READ)
				{
					// need to wait for data to be available for reading, and then retry the same operation
					sslWaitOnRead = true;
					timeoutRemaining = socketTimeoutM; // reset the timeout
				}
				if (err == SSL_ERROR_WANT_WRITE)
				{
					// need to wait for the write file descriptor to be able to write and then try again
					sslWaitOnWrite = true;
					timeoutRemaining = socketTimeoutM; // reset the timeout
				}
				else
				{
					// an error occured
					if ((err == SSL_ERROR_SYSCALL) && (ERR_peek_error() == 0) && (bytes == -1))
					{
						// an error in the system call occured
						openSslError("reading from secure socket");
						if (loggerM_ptr && (loggerM_ptr->getLogMask() & LOG_ERROR))
						{
							loggerM_ptr->text(LOG_NONE, 1, "    read() error code = %d", WSAGetLastError());
						}
					}
					else
					{
						openSslError("reading from secure socket");
					}
					return -1;
				}
			}
		}
		else if (sel == 0)
		{
			// no data at the end of the timeout
			if (--timeoutRemaining > 0)
			{
				// still have time left on the timeout, go back and wait some more
			}
			else
			{
				// timeout expired
				if (loggerM_ptr)
				{
					loggerM_ptr->text(LOG_ERROR, 2, "Secure Socket - Connection timed-out while waiting to receive data");
				}
				return -1;
			}
		}
		else if (sel == SOCKET_ERROR)
		{
			// socket error
			if (loggerM_ptr)
			{
				loggerM_ptr->text(LOG_ERROR, 2, "Secure Socket - Error waiting to receive data (error code %d)", WSAGetLastError());
			}
			return -1;
		}
		else
		{
			// unknown error
			if (loggerM_ptr)
			{
				loggerM_ptr->text(LOG_ERROR, 2, "Secure Socket - Unknown error while waiting to receive data (select returned %d)", sel);
			}
			return -1;
		}
	}

	return read_bytes;
}