示例#1
0
bool
SSLClient::sslConnect(int fd, std::string &hostname, short port)
{
    GNASH_REPORT_FUNCTION;
    int ret;

    if (!_ctx) {
	if (!sslSetupCTX()) {
	    return false;
	}
    }

    _ssl.reset(SSL_new(_ctx.get()));
	
//     // Make a tcp/ip connect to the server
//     if (createClient(hostname, getPort()) == false) {
//         log_error("Can't connect to server %s", hostname);
//         return false;
//     }

    // Handshake the server
    ERR_clear_error();
#if 0
    _bio.reset(BIO_new_socket(fd, BIO_NOCLOSE));
#else
//     BIO_set_conn_hostname(_bio.get(), _hostname.c_str());
    _bio.reset(BIO_new_connect(const_cast<char *>(_hostname.c_str())));

    BIO_set_conn_int_port(_bio.get(), &port);
    log_debug("PORT is: %d", BIO_get_conn_port(_bio.get()));

    if (BIO_do_connect(_bio.get()) <= 0) {
        log_error("Error connecting to remote machine: %s",
		  ERR_reason_error_string(ERR_get_error()));
    }
#endif

    SSL_set_bio(_ssl.get(), _bio.get(), _bio.get());
    SSL_set_connect_state(_ssl.get());
    
    if ((ret = SSL_connect(_ssl.get())) < 0) {
        log_error("Can't connect to SSL server %s", hostname);
 	log_error("Error was: \"%s\"!", ERR_reason_error_string(ERR_get_error()));
        return false;
    } else {
        log_debug("Connected to SSL server %s", hostname);
    }

    ERR_clear_error();
#if 0
    if (_need_server_auth) {
 	checkCert(hostname);
    }
#endif
    
    return true;
}
示例#2
0
static BIO *
my_connect_ssl(char *host, int port, SSL_CTX **ctx) {
  BIO *conn = 0;

  if (!(conn = BIO_new_ssl_connect(*ctx))) goto error_exit;
  BIO_set_conn_hostname(conn, host);
  BIO_set_conn_int_port(conn, &port);

  if (BIO_do_connect(conn) <= 0) goto error_exit;
  return conn;

error_exit:
  if (conn) BIO_free_all(conn);
  return 0;
}
示例#3
0
static BIO *
my_connect(char *host, int port, int ssl, SSL_CTX **ctx) {
  BIO *conn;
  SSL *ssl_ptr;

  if (ssl) {
    if (!(conn = my_connect_ssl(host, port, ctx))) goto error_exit;
    BIO_get_ssl(conn, &ssl_ptr);
    if (!verify_cert_hostname(SSL_get_peer_certificate(ssl_ptr), host))
      goto error_exit;
    if (SSL_get_verify_result(ssl_ptr) != X509_V_OK) goto error_exit;
    return conn;
  }

  if (!(conn = BIO_new_connect(host))) goto error_exit;
  BIO_set_conn_int_port(conn, &port);
  if (BIO_do_connect(conn) <= 0) goto error_exit;
  return conn;

error_exit:
  if (conn) BIO_free_all(conn);
  return 0;
}
示例#4
0
文件: tcp.c 项目: Auto-Droid/FreeRDP
BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port, int timeout)
{
	int status;
	UINT32 option_value;
	socklen_t option_len;

	if (!hostname)
		return FALSE;

	if (hostname[0] == '/')
	{
		tcp->sockfd = freerdp_uds_connect(hostname);

		if (tcp->sockfd < 0)
			return FALSE;

		tcp->socketBio = BIO_new_fd(tcp->sockfd, 1);

		if (!tcp->socketBio)
			return FALSE;
	}
	else
	{
		fd_set cfds;
		struct timeval tv;

		tcp->socketBio = BIO_new(BIO_s_connect());

		if (!tcp->socketBio)
			return FALSE;

		if (BIO_set_conn_hostname(tcp->socketBio, hostname) < 0 || BIO_set_conn_int_port(tcp->socketBio, &port) < 0)
			return FALSE;

		BIO_set_nbio(tcp->socketBio, 1);

		status = BIO_do_connect(tcp->socketBio);

		if ((status <= 0) && !BIO_should_retry(tcp->socketBio))
			return FALSE;

		tcp->sockfd = BIO_get_fd(tcp->socketBio, NULL);

		if (tcp->sockfd < 0)
			return FALSE;

		if (status <= 0)
		{
			FD_ZERO(&cfds);
			FD_SET(tcp->sockfd, &cfds);

			tv.tv_sec = timeout;
			tv.tv_usec = 0;

			status = select(tcp->sockfd + 1, NULL, &cfds, NULL, &tv);

			if (status == 0)
			{
				return FALSE; /* timeout */
			}
		}

		BIO_set_close(tcp->socketBio, BIO_NOCLOSE);
		BIO_free(tcp->socketBio);

		tcp->socketBio = BIO_new(BIO_s_simple_socket());

		if (!tcp->socketBio)
			return -1;

		BIO_set_fd(tcp->socketBio, tcp->sockfd, BIO_CLOSE);
	}

	SetEventFileDescriptor(tcp->event, tcp->sockfd);

	tcp_get_ip_address(tcp);
	tcp_get_mac_address(tcp);

	option_value = 1;
	option_len = sizeof(option_value);

	if (setsockopt(tcp->sockfd, IPPROTO_TCP, TCP_NODELAY, (void*) &option_value, option_len) < 0)
		fprintf(stderr, "%s: unable to set TCP_NODELAY\n", __FUNCTION__);

	/* receive buffer must be a least 32 K */
	if (getsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, &option_len) == 0)
	{
		if (option_value < (1024 * 32))
		{
			option_value = 1024 * 32;
			option_len = sizeof(option_value);

			if (setsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, option_len) < 0)
			{
				fprintf(stderr, "%s: unable to set receive buffer len\n", __FUNCTION__);
				return FALSE;
			}
		}
	}

	if (!tcp_set_keep_alive_mode(tcp))
		return FALSE;

	tcp->bufferedBio = BIO_new(BIO_s_buffered_socket());

	if (!tcp->bufferedBio)
		return FALSE;

	tcp->bufferedBio->ptr = tcp;

	tcp->bufferedBio = BIO_push(tcp->bufferedBio, tcp->socketBio);

	return TRUE;
}
示例#5
0
文件: context.c 项目: esmil/lem-ssl
static int
context_connect(lua_State *T)
{
	struct lem_ssl_context *c;
	const char *hostname;
	int port;
	BIO *bio;
	SSL *ssl;
	int ret;
	const char *msg;
	struct lem_ssl_stream *s;

	luaL_checktype(T, 1, LUA_TUSERDATA);
	c = lua_touserdata(T, 1);
	hostname = luaL_checkstring(T, 2);
	port = (int)luaL_optnumber(T, 3, -1);

	if (c->ctx == NULL) {
		lua_pushnil(T);
		lua_pushliteral(T, "closed");
		return 2;
	}

	bio = BIO_new(BIO_s_connect());
	if (bio == NULL) {
		lua_pushnil(T);
		lua_pushfstring(T, "error creating BIO: %s",
		                ERR_reason_error_string(ERR_get_error()));
		return 2;
	}
	BIO_set_conn_hostname(bio, hostname);
	if (port > 0)
		BIO_set_conn_int_port(bio, (char *)&port);
	BIO_set_nbio(bio, 1);

	ssl = SSL_new(c->ctx);
	if (ssl == NULL) {
		lua_pushnil(T);
		lua_pushfstring(T, "error creating SSL connection: %s",
		                ERR_reason_error_string(ERR_get_error()));
		return 2;
	}
	SSL_set_bio(ssl, bio, bio);

	ret = SSL_connect(ssl);
	switch (SSL_get_error(ssl, ret)) {
	case SSL_ERROR_NONE:
		lem_debug("SSL_ERROR_NONE");
		s = stream_new(T, ssl, NULL, 0);
		return 1;

	case SSL_ERROR_ZERO_RETURN:
		lem_debug("SSL_ERROR_ZERO_RETURN");
		msg = "connection closed unexpectedly";
		break;

	case SSL_ERROR_WANT_READ:
		lem_debug("SSL_ERROR_WANT_READ");
		lua_settop(T, 0);
		s = stream_new(T, ssl, connect_handler, EV_READ);
		s->T = T;
		ev_io_start(EV_G_ &s->w);
		return lua_yield(T, 1);

	case SSL_ERROR_WANT_WRITE:
		lem_debug("SSL_ERROR_WANT_WRITE");
	case SSL_ERROR_WANT_CONNECT:
		lem_debug("SSL_ERROR_WANT_CONNECT");
		lua_settop(T, 0);
		s = stream_new(T, ssl, connect_handler, EV_WRITE);
		s->T = T;
		ev_io_start(EV_G_ &s->w);
		return lua_yield(T, 1);

	case SSL_ERROR_SYSCALL:
		lem_debug("SSL_ERROR_SYSCALL");
		{
			long e = ERR_get_error();

			if (e)
				msg = ERR_reason_error_string(e);
			else if (ret == 0)
				msg = "connection closed unexpectedly";
			else
				msg = strerror(errno);

		}
		break;

	case SSL_ERROR_SSL:
		lem_debug("SSL_ERROR_SSL");
		msg = ERR_reason_error_string(ERR_get_error());
		break;

	default:
		lem_debug("SSL_ERROR_* (default)");
		msg = "unexpected error from SSL library";
	}

	lua_pushnil(T);
	lua_pushfstring(T, "error establishing SSL connection: %s", msg);
	SSL_free(ssl);
	return 2;
}
示例#6
0
文件: net.c 项目: slaeshjag/fanbot3
int getPageFromURL(char *rurl, char *usrname, char *password, char **buff) {
	int port;
	char *host, *bitbucket, *url, *foo;
	BIO *bio;
	SSL_CTX *ctx;
	SSL *ssl;
	
	if (rurl == NULL) {
		return NET_ERROR_NO_SUCH_HOST;
	}
	
	if ((url = malloc(strlen(rurl) + 1)) == NULL) {
		fprintf(stderr, "Error: Out of RAM.\n");
		return NET_ERROR_GENERAL_LOCAL_ERROR;
	}
	
	sprintf(url, "%s", rurl);
	
	if (strstr(url, "https://") != url) {
		fprintf(stderr, "Error: unhandled protocol in URL: %s\n", url);
		free(url);
		return NET_ERROR_BAD_PROTOCOL;
	}
	
	url += 8;
	
	if (strstr(url, "/") != NULL) {
		bitbucket = strstr(url, "/");
		*bitbucket = '\0';
	} else
		bitbucket = NULL;
		
	if ((host = malloc(strlen(url) + 1)) == NULL) {
		url -= 8;
		free(url);
		fprintf(stderr, "Error: Out of RAM.\n");
		return NET_ERROR_GENERAL_LOCAL_ERROR;
	}
		
	sprintf(host, "%s", url);
	if ((foo = strstr(host, ":")) != NULL) {
		*foo = 0;
	}
	
	if (strstr(url, ":") != NULL) {
		port = atoi(1 + strstr(url, ":"));
	} else {
		port = 443;
	}
	
	if (bitbucket != NULL) 
		*bitbucket = '/';
	
	ctx = SSL_CTX_new(SSLv23_client_method());
	if (!(bio = BIO_new_ssl_connect(ctx))) {
		fprintf(stderr, "Unable to allocate a BIO\n");
		return NET_ERROR_GENERAL_LOCAL_ERROR;
	}

	BIO_get_ssl(bio, &ssl);
	SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
	BIO_set_conn_hostname(bio, host);
	BIO_set_conn_int_port(bio, &port);

	if (BIO_do_connect(bio) < 0)
		return NET_ERROR_NO_SUCH_HOST;
	
	BIO_write(bio, "GET ", 4);
	fprintf(stderr, "Contacting %s port %i url %s\n", host, port, bitbucket);
	
	if (bitbucket != NULL)
		BIO_write(bio, bitbucket, strlen(bitbucket));
	else 
		BIO_write(bio, "/", 1);
	
	BIO_write(bio, " HTTP/1.0\r\n", 11);
	BIO_write(bio, NET_USER_AGENT, strlen(NET_USER_AGENT));
	BIO_write(bio, "Host: ", 6);
	BIO_write(bio, host, strlen(host));
	BIO_write(bio, "\r\n", 2);
	
	BIO_write(bio, "\r\n\r\n", 4);
	
	*buff = getURLData(bio, host);
	url -= 8;
	free(url);
	free(host);
	BIO_free_all(bio);
	SSL_CTX_free(ctx);
	
	if (*buff == NULL)
		return NET_ERROR_NO_DATA_FROM_SERVER;
	
	return NET_NO_ERROR;
}
示例#7
0
文件: tcp.c 项目: andrejza/FreeRDP
BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port, int timeout)
{
	int status;
	UINT32 option_value;
	socklen_t option_len;

	if (!hostname)
		return FALSE;

	if (hostname[0] == '/')
		tcp->ipcSocket = TRUE;

	if (tcp->ipcSocket)
	{
		tcp->sockfd = freerdp_uds_connect(hostname);

		if (tcp->sockfd < 0)
			return FALSE;

		tcp->socketBio = BIO_new(BIO_s_simple_socket());

		if (!tcp->socketBio)
			return FALSE;

		BIO_set_fd(tcp->socketBio, tcp->sockfd, BIO_CLOSE);
	}
	else
	{
#ifdef HAVE_POLL_H
		struct pollfd pollfds;
#else
		fd_set cfds;
		struct timeval tv;
#endif

#ifdef NO_IPV6
		tcp->socketBio = BIO_new(BIO_s_connect());

		if (!tcp->socketBio)
			return FALSE;

		if (BIO_set_conn_hostname(tcp->socketBio, hostname) < 0 || BIO_set_conn_int_port(tcp->socketBio, &port) < 0)
			return FALSE;

		BIO_set_nbio(tcp->socketBio, 1);

		status = BIO_do_connect(tcp->socketBio);

		if ((status <= 0) && !BIO_should_retry(tcp->socketBio))
			return FALSE;

		tcp->sockfd = BIO_get_fd(tcp->socketBio, NULL);

		if (tcp->sockfd < 0)
			return FALSE;
#else /* NO_IPV6 */
		struct addrinfo hints = {0};
		struct addrinfo *result;
		struct addrinfo *tmp;
		char port_str[11];

		//ZeroMemory(&hints, sizeof(struct addrinfo));
		hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
		hints.ai_socktype = SOCK_STREAM;
		/*
		 * FIXME: the following is a nasty workaround. Find a cleaner way:
		 * Either set port manually afterwards or get it passed as string?
		 */
		sprintf_s(port_str, 11, "%u", port);

		status = getaddrinfo(hostname, port_str, &hints, &result);
		if (status) {
			fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
			return FALSE;
		}

		/* For now prefer IPv4 over IPv6. */
		tmp = result;
		if (tmp->ai_family == AF_INET6 && tmp->ai_next != 0)
		{
			while ((tmp = tmp->ai_next))
			{
				if (tmp->ai_family == AF_INET)
					break;
			}
			if (!tmp)
				tmp = result;
		}
		tcp->sockfd = socket(tmp->ai_family, tmp->ai_socktype, tmp->ai_protocol);

		if (tcp->sockfd  < 0) {
			freeaddrinfo(result);
			return FALSE;
		}

		if (connect(tcp->sockfd, tmp->ai_addr, tmp->ai_addrlen) < 0) {
			fprintf(stderr, "connect: %s\n", strerror(errno));
			freeaddrinfo(result);
			return FALSE;
		}
		freeaddrinfo(result);
		tcp->socketBio = BIO_new_socket(tcp->sockfd, BIO_NOCLOSE);

		/* TODO: make sure the handshake is done by querying the bio */
		//		if (BIO_should_retry(tcp->socketBio))
		//          return FALSE;
#endif /* NO_IPV6 */

		if (status <= 0)
		{
#ifdef HAVE_POLL_H
			pollfds.fd = tcp->sockfd;
			pollfds.events = POLLOUT;
			pollfds.revents = 0;
			do
			{
				status = poll(&pollfds, 1, timeout * 1000);
			}
			while ((status < 0) && (errno == EINTR));
#else
			FD_ZERO(&cfds);
			FD_SET(tcp->sockfd, &cfds);

			tv.tv_sec = timeout;
			tv.tv_usec = 0;

			status = _select(tcp->sockfd + 1, NULL, &cfds, NULL, &tv);
#endif
			if (status == 0)
			{
				return FALSE; /* timeout */
			}
		}

		(void)BIO_set_close(tcp->socketBio, BIO_NOCLOSE);
		BIO_free(tcp->socketBio);

		tcp->socketBio = BIO_new(BIO_s_simple_socket());

		if (!tcp->socketBio)
			return FALSE;

		BIO_set_fd(tcp->socketBio, tcp->sockfd, BIO_CLOSE);
	}

	SetEventFileDescriptor(tcp->event, tcp->sockfd);

	tcp_get_ip_address(tcp);
	tcp_get_mac_address(tcp);

	option_value = 1;
	option_len = sizeof(option_value);

	if (!tcp->ipcSocket)
	{
		if (setsockopt(tcp->sockfd, IPPROTO_TCP, TCP_NODELAY, (void*) &option_value, option_len) < 0)
			WLog_ERR(TAG,  "unable to set TCP_NODELAY");
	}

	/* receive buffer must be a least 32 K */
	if (getsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, &option_len) == 0)
	{
		if (option_value < (1024 * 32))
		{
			option_value = 1024 * 32;
			option_len = sizeof(option_value);

			if (setsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, option_len) < 0)
			{
				WLog_ERR(TAG,  "unable to set receive buffer len");
				return FALSE;
			}
		}
	}

	if (!tcp->ipcSocket)
	{
		if (!tcp_set_keep_alive_mode(tcp))
			return FALSE;
	}

	tcp->bufferedBio = BIO_new(BIO_s_buffered_socket());

	if (!tcp->bufferedBio)
		return FALSE;

	tcp->bufferedBio->ptr = tcp;

	tcp->bufferedBio = BIO_push(tcp->bufferedBio, tcp->socketBio);

	return TRUE;
}