bool BaseSSLProtocol::SignalInputData(IOBuffer &buffer) { //1. get the SSL input buffer BIO *pInBio = SSL_get_rbio(_pSSL); //2. dump all the data from the network inside the ssl input BIO_write(pInBio, GETIBPOINTER(buffer), GETAVAILABLEBYTESCOUNT(buffer)); buffer.IgnoreAll(); //3. Do we have to do some handshake? if (!_sslHandshakeCompleted) { if (!DoHandshake()) { FATAL("Unable to do the SSL handshake"); return false; } if (!_sslHandshakeCompleted) { return true; } } //4. Read the actual data an put it in the descrypted input buffer int32_t read = 0; while ((read = SSL_read(_pSSL, _pReadBuffer, MAX_SSL_READ_BUFFER)) > 0) { _inputBuffer.ReadFromBuffer(_pReadBuffer, (uint32_t) read); } if (read < 0) { int32_t error = SSL_get_error(_pSSL, read); if (error != SSL_ERROR_WANT_READ && error != SSL_ERROR_WANT_WRITE) { FATAL("Unable to read data: %d", error); return false; } } //6. If we have pending data inside the decrypted buffer, bubble it up on the protocol stack if (GETAVAILABLEBYTESCOUNT(_inputBuffer) > 0) { if (_pNearProtocol != NULL) { if (!_pNearProtocol->SignalInputData(_inputBuffer)) { FATAL("Unable to signal near protocol for new data"); return false; } } } //7. After the data was sent on the upper layers, we might have outstanding //data that needs to be sent. return PerformIO(); }
void CScrobbler::Process() { CLog::Log(LOGDEBUG, "%s: Thread started.", m_strLogPrefix.c_str()); if (!m_pHttp) { // Hack since CFileCurl isn't threadsafe if (!(m_pHttp = new XFILE::CFileCurl)) return; } XbmcThreads::CEventGroup eventGroup(&m_hEvent, getStopEvent(), NULL); while (!m_bStop) { eventGroup.wait(); if (m_bStop) break; if (m_strSessionID.IsEmpty()) { time_t now = time(NULL); // We need to handshake. if (m_bBanned || m_bBadAuth || ((now - m_lastFailedHandshake) < m_failedHandshakeDelay)) continue; if (!DoHandshake(now)) continue; } int action = 0; { CSingleLock lock(m_actionLock); action = m_action; m_action = 0; } if (action == SCROBBLER_ACTION_NOWPLAYING) DoNowPlayingNotification(); else if (action == SCROBBLER_ACTION_SUBMIT) { m_bSubmitting = true; DoSubmission(); m_bSubmitting = false; } } delete m_pHttp; // More of aforementioned hack m_pHttp = NULL; CLog::Log(LOGDEBUG, "%s: Thread ended.", m_strLogPrefix.c_str()); }
bool BaseSSLProtocol::EnqueueForOutbound() { //1. Is the SSL handshake completed? if (!_sslHandshakeCompleted) { return DoHandshake(); } //2. Do we have some outstanding data? IOBuffer *pBuffer = _pNearProtocol->GetOutputBuffer(); if (pBuffer == NULL) return true; //3. Encrypt the outstanding data if (SSL_write(_pSSL, GETIBPOINTER(*pBuffer), GETAVAILABLEBYTESCOUNT(*pBuffer)) != (int32_t) GETAVAILABLEBYTESCOUNT(*pBuffer)) { FATAL("Unable to write %u bytes", GETAVAILABLEBYTESCOUNT(*pBuffer)); return false; } pBuffer->IgnoreAll(); //4. Do the actual I/O return PerformIO(); }
bool BaseSSLProtocol::Initialize(Variant ¶meters) { //1. Initialize the SSL library if (!_libraryInitialized) { //3. This is the first time we use the library. So we have to //initialize it first SSL_library_init(); //init readable error messages SSL_load_error_strings(); ERR_load_SSL_strings(); ERR_load_CRYPTO_strings(); ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); OpenSSL_add_all_ciphers(); OpenSSL_add_all_digests(); //initialize the random numbers generator InitRandGenerator(); _libraryInitialized = true; } //2. Initialize the global context if (!InitGlobalContext(parameters)) { FATAL("Unable to initialize global context"); return false; } //3. create connection SSL context _pSSL = SSL_new(_pGlobalSSLContext); if (_pSSL == NULL) { FATAL("Unable to create SSL connection context"); return false; } //4. setup the I/O buffers SSL_set_bio(_pSSL, BIO_new(BIO_s_mem()), BIO_new(BIO_s_mem())); return DoHandshake(); }