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; } }
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; }
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; }
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; }
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; }
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; }
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; }