johnson-pkt / twitcurl

Automatically exported from code.google.com/p/twitcurl
0 stars 0 forks source link

twitCurl::oAuthHandlePIN problems #26

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
In twitCurl::oAuthHandlePIN there are several places where string::find is 
called on oAuthLibDefaults. The result of string::find is not checked and 
assumed to be valid (the string was found). However if an incorrect 
username/password is supplied the returned data from twitter is html, and the 
expected finds do not work. By not checking the return vaules of find the 
result is a large buffer overrun in CHMAC_SHA1::AppendBuf2 (or was it 
AppendBuff1 - can't recall now), resulting in exception.

The fix is of course to check the results of the find calls as below...
bool twitCurl::oAuthHandlePIN( const std::string& authorizeUrl /* in */ )
{
    std::string dataStr;
    std::string oAuthHttpHeader;
    std::string authenticityTokenVal;
    std::string oauthTokenVal;
    std::string pinCodeVal;
    unsigned long httpStatusCode = 0;
    size_t nPosStart, nPosEnd;
    struct curl_slist* pOAuthHeaderList = NULL;

    /* Prepare standard params */
    prepareStandardParams();

    /* Set OAuth header */
    m_oAuth.getOAuthHeader( eOAuthHttpGet, authorizeUrl, dataStr, oAuthHttpHeader );
    if( oAuthHttpHeader.length() )
    {
        pOAuthHeaderList = curl_slist_append( pOAuthHeaderList, oAuthHttpHeader.c_str() );
        if( pOAuthHeaderList )
        {
            curl_easy_setopt( m_curlHandle, CURLOPT_HTTPHEADER, pOAuthHeaderList );
        }
    }

    /* Set http request and url */
    curl_easy_setopt( m_curlHandle, CURLOPT_HTTPGET, 1 );
    curl_easy_setopt( m_curlHandle, CURLOPT_URL, authorizeUrl.c_str() );

    /* Send http request */
    if( CURLE_OK == curl_easy_perform( m_curlHandle ) )
    {
        if( pOAuthHeaderList )
        {
            curl_easy_getinfo( m_curlHandle, CURLINFO_HTTP_CODE, &httpStatusCode );

            // Now, let's find the authenticity token and oauth token 
            nPosStart = m_callbackData.find( oAuthLibDefaults::OAUTHLIB_AUTHENTICITY_TOKEN_TWITTER_RESP_KEY );
            if (nPosStart != (size_t)-1)
            {
              nPosStart += oAuthLibDefaults::OAUTHLIB_AUTHENTICITY_TOKEN_TWITTER_RESP_KEY.length();
              nPosEnd = m_callbackData.substr( nPosStart ).find( oAuthLibDefaults::OAUTHLIB_TOKEN_END_TAG_TWITTER_RESP );
              if (nPosEnd != (size_t)-1)
              {
                authenticityTokenVal = m_callbackData.substr( nPosStart, nPosEnd );
                nPosStart = m_callbackData.find( oAuthLibDefaults::OAUTHLIB_TOKEN_TWITTER_RESP_KEY );
                if (nPosStart != (size_t)-1)
                {
                  nPosStart += oAuthLibDefaults::OAUTHLIB_TOKEN_TWITTER_RESP_KEY.length();
                  nPosEnd = m_callbackData.substr( nPosStart ).find( oAuthLibDefaults::OAUTHLIB_TOKEN_END_TAG_TWITTER_RESP );
                  if (nPosEnd != (size_t)-1)
                    oauthTokenVal = m_callbackData.substr( nPosStart, nPosEnd );
                  else
                  {
                    curl_slist_free_all( pOAuthHeaderList );
                    return false;
                  }
                }
              }
              else
              {
                curl_slist_free_all( pOAuthHeaderList );
                return false;
              }
            }
            else
            {
              curl_slist_free_all( pOAuthHeaderList );
              return false;
            }
            curl_slist_free_all( pOAuthHeaderList );
        }
    } 
    else if( pOAuthHeaderList )
    {
        curl_slist_free_all( pOAuthHeaderList );
        return false;
    }

    // Second phase for the authorization 
    pOAuthHeaderList = NULL;
    oAuthHttpHeader.clear();

    /* Prepare standard params */
    prepareStandardParams();

    /*
    Now, we need to make a data string for POST operation
    which includes oauth token, authenticity token, username, password.
    */
    dataStr = oAuthLibDefaults::OAUTHLIB_TOKEN_KEY + "=" + oauthTokenVal + "&" +                      \
              oAuthLibDefaults::OAUTHLIB_AUTHENTICITY_TOKEN_KEY + "=" + authenticityTokenVal + "&" +  \
              oAuthLibDefaults::OAUTHLIB_SESSIONUSERNAME_KEY + "=" + getTwitterUsername() + "&" +     \
              oAuthLibDefaults::OAUTHLIB_SESSIONPASSWORD_KEY + "=" + getTwitterPassword();

    /* Set OAuth header */
    m_oAuth.getOAuthHeader( eOAuthHttpPost, authorizeUrl, dataStr, oAuthHttpHeader );
    if( oAuthHttpHeader.length() )
    {
        pOAuthHeaderList = curl_slist_append( pOAuthHeaderList, oAuthHttpHeader.c_str() );
        if( pOAuthHeaderList )
        {
            curl_easy_setopt( m_curlHandle, CURLOPT_HTTPHEADER, pOAuthHeaderList );
        }
    }

    /* Set http request and url */
    curl_easy_setopt( m_curlHandle, CURLOPT_POST, 1 );
    curl_easy_setopt( m_curlHandle, CURLOPT_URL, authorizeUrl.c_str() );
    curl_easy_setopt( m_curlHandle, CURLOPT_COPYPOSTFIELDS, dataStr.c_str() );

    /* Send http request */
    if( CURLE_OK == curl_easy_perform( m_curlHandle ) )
    {
        if( pOAuthHeaderList )
        {
            curl_easy_getinfo( m_curlHandle, CURLINFO_HTTP_CODE, &httpStatusCode );

            // Now, let's find the PIN CODE  
            nPosStart = m_callbackData.find( oAuthLibDefaults::OAUTHLIB_PIN_TWITTER_RESP_KEY );
            if (nPosStart != (size_t)-1)
            {
              nPosStart += oAuthLibDefaults::OAUTHLIB_PIN_TWITTER_RESP_KEY.length();
              nPosEnd = m_callbackData.substr( nPosStart ).find( oAuthLibDefaults::OAUTHLIB_PIN_END_TAG_TWITTER_RESP );
              if (nPosEnd != (size_t)-1)
              {
                pinCodeVal = m_callbackData.substr( nPosStart, nPosEnd );
                getOAuth().setOAuthPin( pinCodeVal );
                curl_slist_free_all( pOAuthHeaderList );
                return true;
              }
              else
              {
                curl_slist_free_all( pOAuthHeaderList );
                return false;
              }
            }
            else
            {
              curl_slist_free_all( pOAuthHeaderList );
              return false;
            }
        }
    } 
    else if( pOAuthHeaderList )
      curl_slist_free_all( pOAuthHeaderList );
    return false;
}

Original issue reported on code.google.com by dtbobmil...@gmail.com on 13 Feb 2012 at 12:54

GoogleCodeExporter commented 8 years ago
Added error handling for string::find() failure cases. Thanks :)

Original comment by swatkat....@gmail.com on 7 Apr 2012 at 5:05