Пример #1
0
void StreamPeerMbedTLS::poll() {

	ERR_FAIL_COND(!connected);
	ERR_FAIL_COND(!base.is_valid());

	int ret = mbedtls_ssl_read(&ssl, NULL, 0);

	if (ret < 0 && ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
		_print_error(ret);
		disconnect_from_stream();
		return;
	}
}
Пример #2
0
Error StreamPeerMbedTLS::connect_to_stream(Ref<StreamPeer> p_base, bool p_validate_certs, const String &p_for_hostname) {

	base = p_base;
	int ret = 0;
	int authmode = p_validate_certs ? MBEDTLS_SSL_VERIFY_REQUIRED : MBEDTLS_SSL_VERIFY_NONE;

	mbedtls_ssl_init(&ssl);
	mbedtls_ssl_config_init(&conf);
	mbedtls_ctr_drbg_init(&ctr_drbg);
	mbedtls_entropy_init(&entropy);

	ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0);
	if (ret != 0) {
		ERR_PRINTS(" failed\n  ! mbedtls_ctr_drbg_seed returned an error" + itos(ret));
		return FAILED;
	}

	mbedtls_ssl_config_defaults(&conf,
			MBEDTLS_SSL_IS_CLIENT,
			MBEDTLS_SSL_TRANSPORT_STREAM,
			MBEDTLS_SSL_PRESET_DEFAULT);

	mbedtls_ssl_conf_authmode(&conf, authmode);
	mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL);
	mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
	mbedtls_ssl_conf_dbg(&conf, my_debug, stdout);
	mbedtls_ssl_setup(&ssl, &conf);
	mbedtls_ssl_set_hostname(&ssl, p_for_hostname.utf8().get_data());

	mbedtls_ssl_set_bio(&ssl, this, bio_send, bio_recv, NULL);

	while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
		if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
			ERR_PRINTS("TLS handshake error: " + itos(ret));
			_print_error(ret);
			status = STATUS_ERROR_HOSTNAME_MISMATCH;
			return FAILED;
		}
	}

	connected = true;
	status = STATUS_CONNECTED;

	return OK;
}
Пример #3
0
Error StreamPeerMbedTLS::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_received) {

	ERR_FAIL_COND_V(!connected, ERR_UNCONFIGURED);

	r_received = 0;

	int ret = mbedtls_ssl_read(&ssl, p_buffer, p_bytes);
	if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
		ret = 0; // non blocking io
	} else if (ret <= 0) {
		_print_error(ret);
		disconnect_from_stream();
		return ERR_CONNECTION_ERROR;
	}

	r_received = ret;
	return OK;
}
Пример #4
0
cSocket::Status cOpenSSLSocket::Send( const void * data, std::size_t size ) {
	Uint8 * buf = (Uint8*)data;

	while( size > 0 ) {
		int ret = SSL_write( mSSL, buf, size );

		if ( ret <= 0 ) {
			_print_error(ret);

			Disconnect();

			return cSocket::Disconnected;
		}

		buf+=ret;
		size-=ret;
	}

	return cSocket::Done;
}
Пример #5
0
Error StreamPeerMbedTLS::put_partial_data(const uint8_t *p_data, int p_bytes, int &r_sent) {

	ERR_FAIL_COND_V(!connected, ERR_UNCONFIGURED);

	r_sent = 0;

	if (p_bytes == 0)
		return OK;

	int ret = mbedtls_ssl_write(&ssl, p_data, p_bytes);
	if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
		ret = 0; // non blocking io
	} else if (ret <= 0) {
		_print_error(ret);
		disconnect_from_stream();
		return ERR_CONNECTION_ERROR;
	}

	r_sent = ret;
	return OK;
}
Пример #6
0
cSocket::Status cOpenSSLSocket::Receive( void * data, std::size_t size, std::size_t& received ) {
	if ( size==0 ) {
		received = 0;
		return cSocket::Done;
	}

	size_t iniSize = size;

	Uint8 * buf = (Uint8*)data;

	while( size > 0 ) {
		int ret = SSL_read( mSSL, buf, size );

		if ( ret < 0 ) {
			_print_error(ret);

			Disconnect();

			return cSocket::Disconnected;
		} else if ( 0 == ret ) {
			if ( size == iniSize ) {
				return cSocket::Disconnected;
			}

			received = iniSize - size;

			return cSocket::Done;
		}

		buf+=ret;
		size-=ret;
	}

	received = iniSize;

	return cSocket::Done;
}
int
main (int argc, char **argv)
{
        int             kcmdline_parsed;
        Display        *display = NULL;
        int             ret = HELPER_NO_ACCEL;
        GOptionContext *context;
        GError         *error = NULL;
        char           *renderer = NULL;

        setlocale (LC_ALL, "");

        context = g_option_context_new (NULL);
        g_option_context_add_main_entries (context, entries, NULL);

        if (!g_option_context_parse (context, &argc, &argv, &error)) {
                g_error ("Can't parse command line: %s\n", error->message);
                g_error_free (error);
                goto out;
        }

        kcmdline_parsed = _parse_kcmdline ();
        if (kcmdline_parsed > CMDLINE_UNSET) {
                if (kcmdline_parsed == CMDLINE_NON_FALLBACK_FORCED) {
                        _print_error ("Non-fallback mode forced by kernel command line.");
                        ret = HELPER_ACCEL;
                        goto out;
                } else if (kcmdline_parsed == CMDLINE_FALLBACK_FORCED) {
                        _print_error ("Fallback mode forced by kernel command line.");
                        goto out;
                }
        }

        display = XOpenDisplay (NULL);
        if (!display) {
                _print_error ("No X display.");
                goto out;
        }

        if (!_has_composite (display)) {
                _print_error ("No composite extension.");
                goto out;
        }

        renderer = _get_hardware_gl (display);
        if (!renderer) {
                _print_error ("No hardware 3D support.");
                goto out;
        }

        if (!_has_texture_from_pixmap (display)) {
                _print_error ("No GLX_EXT_texture_from_pixmap support.");
                goto out;
        }

        if (!_is_max_texture_size_big_enough (display)) {
                _print_error ("GL_MAX_{TEXTURE,RENDERBUFFER}_SIZE is too small.");
                goto out;
        }

        ret = has_llvmpipe ? HELPER_SOFTWARE_RENDERING : HELPER_ACCEL;

        if (print_renderer)
                g_print ("%s", renderer);

out:
        if (display)
                XCloseDisplay (display);
        g_free (renderer);

        return ret;
}
static gboolean
_is_gl_renderer_blacklisted (const char *renderer)
{
        FILE *blacklist;
        char *line = NULL;
        size_t line_len = 0;
        gboolean ret = TRUE;

        blacklist = fopen(PKGDATADIR "/hardware-compatibility", "r");
        if (blacklist == NULL)
                goto out;

        while (getline (&line, &line_len, blacklist) != -1) {
                int whitelist = 0;
                const char *re_str;
                regex_t re;
                int status;

                if (line == NULL)
                        break;

                /* Drop trailing \n */
                line[strlen(line) - 1] = '\0';

                if (_is_comment (line)) {
                        free (line);
                        line = NULL;
                        continue;
                }

                if (line[0] == '+')
                        whitelist = 1;
                else if (line[0] == '-')
                        whitelist = 0;
                else {
                        _print_error ("Invalid syntax in this line for hardware compatibility:");
                        _print_error (line);
                        free (line);
                        line = NULL;
                        continue;
                }

                re_str = line + 1;

                if (regcomp (&re, re_str, REG_EXTENDED|REG_ICASE|REG_NOSUB) != 0) {
                        _print_error ("Cannot use this regular expression for hardware compatibility:");
                        _print_error (re_str);
                } else {
                        status = regexec (&re, renderer, 0, NULL, 0);
                        regfree(&re);

                        if (status == 0) {
                                if (whitelist)
                                        ret = FALSE;
                                goto out;
                        }
                }

                free (line);
                line = NULL;
        }

        ret = FALSE;

out:
        if (line != NULL)
                free (line);

        if (blacklist != NULL)
                fclose (blacklist);

        return ret;
}
Пример #9
0
cSocket::Status cOpenSSLSocket::Connect( const cIpAddress& remoteAddress, unsigned short remotePort, cTime timeout ) {
	if ( mConnected ) {
		Disconnect();
	}

	// Set up a SSL_CTX object, which will tell our BIO object how to do its work
	mCTX = SSL_CTX_new( SSLv23_client_method() );

	if ( mSSLSocket->mValidateCertificate ) {
		if (!sCerts.empty()) {
			//yay for undocumented OpenSSL functions
			X509_STORE * store = SSL_CTX_get_cert_store( mCTX );

			for( size_t i = 0; i < sCerts.size(); i++ ) {
				X509_STORE_add_cert( store, sCerts[i] );
			}
		}

		/* Ask OpenSSL to verify the server certificate.  Note that this
		 * does NOT include verifying that the hostname is correct.
		 * So, by itself, this means anyone with any legitimate
		 * CA-issued certificate for any website, can impersonate any
		 * other website in the world.  This is not good.  See "The
		 * Most Dangerous Code in the World" article at
		 * https://crypto.stanford.edu/~dabo/pubs/abstracts/ssl-client-bugs.html
		 */
		SSL_CTX_set_verify( mCTX, SSL_VERIFY_PEER, NULL );

		/* This is how we solve the problem mentioned in the previous
		 * comment.  We "wrap" OpenSSL's validation routine in our
		 * own routine, which also validates the hostname by calling
		 * the code provided by iSECPartners.  Note that even though
		 * the "Everything You've Always Wanted to Know About
		 * Certificate Validation With OpenSSL (But Were Afraid to
		 * Ask)" paper from iSECPartners says very explicitly not to
		 * call SSL_CTX_set_cert_verify_callback (at the bottom of
		 * page 2), what we're doing here is safe because our
		 * cert_verify_callback() calls X509_verify_cert(), which is
		 * OpenSSL's built-in routine which would have been called if
		 * we hadn't set the callback.  Therefore, we're just
		 * "wrapping" OpenSSL's routine, not replacing it. */
		SSL_CTX_set_cert_verify_callback ( mCTX, CertVerifyCb, this );

		//Let the verify_callback catch the verify_depth error so that we get an appropriate error in the logfile. (??)
		SSL_CTX_set_verify_depth( mCTX, mMaxCertChainDepth + 1 );
	}

	mSSL		= SSL_new( mCTX );

	SSL_set_fd( mSSL, (int)mSSLSocket->mSocket );

	// Set the SSL to automatically retry on failure.
	SSL_set_mode( mSSL , SSL_MODE_AUTO_RETRY );

	mStatus		= cSocket::Done;

	// Same as before, try to connect.
	int result	= SSL_connect( mSSL );

	eePRINTL( "CONNECTION RESULT: %d", result );

	if ( result < 1 ) {
		ERR_print_errors_fp(stdout);

		_print_error(result);

		mStatus	= cSocket::Error;

		return mStatus;
	}

	X509 * peer = SSL_get_peer_certificate( mSSL );

	if ( peer ) {
		bool cert_ok = SSL_get_verify_result(mSSL) == X509_V_OK;

		eePRINTL( "cert_ok: %d", (int)cert_ok );

		mStatus	= cSocket::Done;
	} else if ( mSSLSocket->mValidateCertificate ) {
		mStatus	= cSocket::Error;
	}

	if ( mStatus == cSocket::Done ) {
		mConnected = true;
	}

	return mStatus;
}