CAtomDicti *DecodeDicti( const string &x, unsigned long iStart ) { unsigned long i = iStart + 1; CAtomDicti *pDicti = new CAtomDicti( ); while( i < x.size( ) && x[i] != 'e' ) { CAtom *pKey = Decode( x, i ); if( pKey && dynamic_cast<CAtomString *>( pKey ) ) { i += pKey->EncodedLength( ); string strKey = pKey->toString( ); delete pKey; if( i < x.size( ) ) { CAtom *pValue = Decode( x, i ); if( pValue ) { i += pValue->EncodedLength( ); pDicti->setItem( strKey, pValue ); } else { UTIL_LogPrint( "error decoding dictionary - error decoding value, discarding dictionary\n" ); delete pDicti; return NULL; } } } else { UTIL_LogPrint( "error decoding dictionary - error decoding key, discarding dictionary\n" ); delete pDicti; return NULL; } } return pDicti; }
string EncodeDicti( const CAtomDicti &x ) { map<string, CAtom *> mapDicti = x.getValue( ); string strDest; strDest += "d"; for( map<string, CAtom *> :: iterator i = mapDicti.begin( ); i != mapDicti.end( ); i++ ) { strDest += EncodeString( CAtomString( (*i).first ) ); if( dynamic_cast<CAtomInt *>( (*i).second ) ) strDest += EncodeInt( *dynamic_cast<CAtomInt *>( (*i).second ) ); else if( dynamic_cast<CAtomLong *>( (*i).second ) ) strDest += EncodeLong( *dynamic_cast<CAtomLong *>( (*i).second ) ); else if( dynamic_cast<CAtomString *>( (*i).second ) ) strDest += EncodeString( *dynamic_cast<CAtomString *>( (*i).second ) ); else if( dynamic_cast<CAtomList *>( (*i).second ) ) strDest += EncodeList( *dynamic_cast<CAtomList *>( (*i).second ) ); else if( dynamic_cast<CAtomDicti *>( (*i).second ) ) strDest += EncodeDicti( *dynamic_cast<CAtomDicti *>( (*i).second ) ); } strDest += "e"; return strDest; }
CAtomDicti :: CAtomDicti( const CAtomDicti &c ) { // copy constructor map<string, CAtom *> *pmapDicti = c.getValuePtr( ); for( map<string, CAtom *> :: iterator itAtom = pmapDicti->begin( ); itAtom != pmapDicti->end( ); itAtom++ ) { if( dynamic_cast<CAtomInt *>( (*itAtom).second ) ) setItem( (*itAtom).first, new CAtomInt( *dynamic_cast<CAtomInt *>( (*itAtom).second ) ) ); else if( dynamic_cast<CAtomLong *>( (*itAtom).second ) ) setItem( (*itAtom).first, new CAtomLong( *dynamic_cast<CAtomLong *>( (*itAtom).second ) ) ); else if( dynamic_cast<CAtomString *>( (*itAtom).second ) ) setItem( (*itAtom).first, new CAtomString( *dynamic_cast<CAtomString *>( (*itAtom).second ) ) ); else if( dynamic_cast<CAtomList *>( (*itAtom).second ) ) setItem( (*itAtom).first, new CAtomList( *dynamic_cast<CAtomList *>( (*itAtom).second ) ) ); else if( dynamic_cast<CAtomDicti *>( (*itAtom).second ) ) setItem( (*itAtom).first, new CAtomDicti( *dynamic_cast<CAtomDicti *>( (*itAtom).second ) ) ); else UTIL_LogPrint( ( gmapLANG_CFG["atomdicti_copy_warning"] + "\n" ).c_str( ) ); } }
CAtomDicti :: CAtomDicti( const CAtomDicti &c ) { // copy constructor map<string, CAtom *> *pmapDicti = c.getValuePtr( ); for( map<string, CAtom *> :: iterator i = pmapDicti->begin( ); i != pmapDicti->end( ); i++ ) { if( dynamic_cast<CAtomInt *>( (*i).second ) && dynamic_cast<CAtomInt *>( (*i).second ) != NULL ) setItem( (*i).first, new CAtomInt( *dynamic_cast<CAtomInt *>( (*i).second ) ) ); else if( dynamic_cast<CAtomLong *>( (*i).second ) && dynamic_cast<CAtomLong *>( (*i).second ) != NULL ) setItem( (*i).first, new CAtomLong( *dynamic_cast<CAtomLong *>( (*i).second ) ) ); else if( dynamic_cast<CAtomString *>( (*i).second ) && dynamic_cast<CAtomString *>( (*i).second ) != NULL ) setItem( (*i).first, new CAtomString( *dynamic_cast<CAtomString *>( (*i).second ) ) ); else if( dynamic_cast<CAtomList *>( (*i).second ) && dynamic_cast<CAtomList *>( (*i).second ) != NULL ) setItem( (*i).first, new CAtomList( *dynamic_cast<CAtomList *>( (*i).second ) ) ); else if( dynamic_cast<CAtomDicti *>( (*i).second ) && dynamic_cast<CAtomDicti *>( (*i).second ) != NULL ) setItem( (*i).first, new CAtomDicti( *dynamic_cast<CAtomDicti *>( (*i).second ) ) ); else UTIL_LogPrint( "error copying dictionary - found invalid atom, ignoring\n" ); } }
void CTracker :: serverResponseSignupLilyPOST( struct request_t *pRequest, struct response_t *pResponse, CAtomList *pPost ) { // Set the start time const struct bnbttv btv( UTIL_CurrentTime( ) ); // Verify that the IP is permitted to access the tracker if( m_ucIPBanMode != 0 ) if( IsIPBanned( pRequest, pResponse, btv, gmapLANG_CFG["signup_page"], string( CSS_SIGNUP ), NOT_INDEX ) ) return; string cstrLogin = string( ); string cstrLilyID = string( ); if( pPost ) { // Initialise segment dictionary CAtomDicti *pSegment = 0; CAtom *pDisposition = 0; CAtom *pData = 0; CAtom *pName = 0; CAtom *pFile = 0; // Get the segments from the post vector<CAtom *> vecSegments = pPost->getValue( ); // Loop through the segments for( unsigned long ulCount = 0; ulCount < vecSegments.size( ); ulCount++ ) { // Is the segment a dictionary? if( vecSegments[ulCount]->isDicti( ) ) { // Get the segment dictionary pSegment = (CAtomDicti *)vecSegments[ulCount]; // Get the disposition and the data from the segment dictionary pDisposition = pSegment->getItem( "disposition" ); pData = pSegment->getItem( "data" ); // Did we get a disposition that is a dictionary and has data? if( pDisposition && pDisposition->isDicti( ) && pData ) { // Get the content name from the disposition pName = ( (CAtomDicti *)pDisposition )->getItem( "name" ); // Did we get a content name? if( pName ) { // What is the content name to be tested? string strName = pName->toString( ); if( strName == "us_login") cstrLogin = pData->toString( ); else if( strName == "us_lilyid") cstrLilyID = UTIL_ToLower( pData->toString( ) ); } else { // Output common HTML head HTML_Common_Begin( pRequest, pResponse, gmapLANG_CFG["signup_page"], string( CSS_SIGNUP ), string( ), NOT_INDEX, CODE_400 ); // failed pResponse->strContent += "<p class=\"failed\">" + gmapLANG_CFG["failed"] + "</p>\n"; // Signal a bad request pResponse->strContent += "<p class=\"body_upload\">400 " + gmapLANG_CFG["server_response_400"] + "</p>\n"; // Output common HTML tail HTML_Common_End( pRequest, pResponse, btv, NOT_INDEX, string( CSS_SIGNUP ) ); if( gbDebug ) UTIL_LogPrint( "Login Warning - Bad request (no users name)\n" ); return; } } } } } else { // Output common HTML head HTML_Common_Begin( pRequest, pResponse, gmapLANG_CFG["signup_page"], string( CSS_SIGNUP ), string( ), NOT_INDEX, CODE_400 ); // failed pResponse->strContent += "<p class=\"failed\">" + gmapLANG_CFG["failed"] + "</p>\n"; // Signal a bad request pResponse->strContent += "<p class=\"body_upload\">400 " + gmapLANG_CFG["server_response_400"] + "</p>\n"; // Output common HTML tail HTML_Common_End( pRequest, pResponse, btv, NOT_INDEX, string( CSS_SIGNUP ) ); if( gbDebug ) UTIL_LogPrint( "Upload Warning - Bad request (no post received)\n" ); return; } if( pRequest->user.ucAccess & ACCESS_SIGNUP ) { HTML_Common_Begin( pRequest, pResponse, gmapLANG_CFG["signup_page"], string( CSS_SIGNUP ), string( ), NOT_INDEX, CODE_200 ); if( !cstrLogin.empty( ) && !cstrLilyID.empty( ) ) { // if( cstrLogin[0] == ' ' || cstrLogin[cstrLogin.size( ) - 1] == ' ' || cstrLogin.size( ) > m_uiNameLength ) if( cstrLogin.find( ' ' ) != string :: npos || cstrLogin.find( '.' ) != string :: npos || cstrLogin.find( '%' ) != string :: npos || cstrLogin.find( '&' ) != string :: npos || cstrLilyID.find( ' ' ) != string :: npos || cstrLilyID.find( '.' ) != string :: npos || cstrLilyID.find( '%' ) != string :: npos || cstrLilyID.find( '&' ) != string :: npos || cstrLogin.size( ) > m_uiNameLength ) { // Unable to signup. Your name must be less than " + CAtomInt( m_uiNameLength ).toString( ) + " characters long and it must not start or end with spaces. pResponse->strContent += "<p class=\"signup_failed\">" + UTIL_Xsprintf( gmapLANG_CFG["signup_name_error"].c_str( ), CAtomInt( m_uiNameLength ).toString( ).c_str( ), string( "<a title=\"" + gmapLANG_CFG["navbar_signup"] + "\" href=\"" + RESPONSE_STR_SIGNUP_LILY_HTML + "\">" ).c_str( ), "</a>" ) + "</p>\n\n"; // Output common HTML tail HTML_Common_End( pRequest, pResponse, btv, NOT_INDEX, string( CSS_SIGNUP ) ); return; } time_t tNow = time( 0 ); char pTime[256]; memset( pTime, 0, sizeof( pTime ) / sizeof( char ) ); strftime( pTime, sizeof( pTime ) / sizeof( char ), "%Y %m/%d %H:%M:%S", localtime( &tNow ) ); const string cstrA1( cstrLogin + ":" + gstrRealm + ":" + pTime ); unsigned char szMD5[16]; memset( szMD5, 0, sizeof( szMD5 ) / sizeof( unsigned char ) ); MD5_CTX md5; MD5Init( &md5 ); MD5Update( &md5, (const unsigned char *)cstrA1.c_str( ), (unsigned int)cstrA1.size( ) ); MD5Final( szMD5, &md5 ); const string cstrPass = UTIL_HashToString( string( (char *)szMD5, sizeof( szMD5 ) / sizeof( unsigned char ) ) ).substr( 0, 8 ); const string cstrMail = cstrLilyID + "@bbs.nju.edu.cn"; if( !getUser( cstrLogin, m_ucGuestAccess ).strLogin.empty( ) ) { // Unable to signup. The user \"" + UTIL_RemoveHTML( cstrLogin ) + "\" already exists. pResponse->strContent += "<p class=\"signup_failed\">" + UTIL_Xsprintf( gmapLANG_CFG["signup_exists_error"].c_str( ), UTIL_RemoveHTML( cstrLogin ).c_str( ), string( "<a title=\"" + gmapLANG_CFG["navbar_signup"] + "\" href=\"" + RESPONSE_STR_SIGNUP_LILY_HTML + "\">" ).c_str( ), "</a>" ) + "</p>\n\n"; } else { CMySQLQuery *pQuery = new CMySQLQuery( "SELECT blilyid FROM lily WHERE blilyid=\'" + UTIL_StringToMySQL( cstrLilyID ) + "\'" ); if( pQuery->nextRow( ).size( ) == 1 ) { pResponse->strContent += "<p class=\"signup_failed\">" + UTIL_Xsprintf( gmapLANG_CFG["signup_exists_error_lily"].c_str( ), UTIL_RemoveHTML( cstrLogin ).c_str( ), UTIL_RemoveHTML( cstrLilyID ).c_str( ), string( "<a title=\"" + gmapLANG_CFG["navbar_signup"] + "\" href=\"" + RESPONSE_STR_SIGNUP_LILY_HTML + "\">" ).c_str( ), "</a>" ) + "</p>\n\n"; } else { if( addUser( cstrLogin, cstrPass, m_ucMemberAccess, cstrMail ) ) { CMySQLQuery mq01( "INSERT INTO lily (blilyid,busername,bpassword) VALUES(\'" + UTIL_StringToMySQL( cstrLilyID ) + "\',\'" + UTIL_StringToMySQL( cstrLogin ) + "\',\'" + UTIL_StringToMySQL( cstrPass ) + "\')" ); system( string( "echo \"ID: " + cstrLogin + " Password: "******"\" | mutt -s \"ZiJingBT\" " + cstrMail ).c_str( ) ); // Thanks! You've successfully signed up! pResponse->strContent += "<p class=\"signup_ok\">" + UTIL_Xsprintf( gmapLANG_CFG["signup_success_lily"].c_str( ), UTIL_RemoveHTML( cstrLilyID ).c_str( ), string( "<a title=\"" + gmapLANG_CFG["navbar_signup"] + "\" href=\"" + RESPONSE_STR_LOGIN_HTML + "\">" ).c_str( ), "</a>" ) + "</p>\n\n"; } else pResponse->strContent += "<p class=\"signup_failed\">" + UTIL_Xsprintf( gmapLANG_CFG["users_max_create_fail"].c_str( ), string( "<a title=\"" + gmapLANG_CFG["navbar_users"] + "\" href=\"" + RESPONSE_STR_USERS_HTML + "\">" ).c_str( ), "</a>" ) + "</p>\n"; } delete pQuery; } HTML_Common_End( pRequest, pResponse, btv, NOT_INDEX, string( CSS_SIGNUP ) ); } } else { //Unable to signup. You must fill in all the fields. pResponse->strContent += "<p class=\"signup_failed\">" + UTIL_Xsprintf( gmapLANG_CFG["signup_fields_error"].c_str( ), string( "<a title=\"" + gmapLANG_CFG["navbar_signup"] + "\" href=\"" + RESPONSE_STR_SIGNUP_LILY_HTML + "\">" ).c_str( ), "</a>" ) + "</p>\n\n"; // Output common HTML tail HTML_Common_End( pRequest, pResponse, btv, NOT_INDEX, string( CSS_SIGNUP ) ); return; } }
inline CAtomList *UTIL_DecodeHTTPPost( const string &cstrPost ) { // find the boundary string :: size_type iBoundary = cstrPost.find( C_STR_BOUNDARY ); if( iBoundary == string :: npos ) return 0; iBoundary += ( sizeof(C_STR_BOUNDARY) - 1 ); string strBoundary = cstrPost.substr( iBoundary ); const string :: size_type ciBoundEnd( strBoundary.find( C_STR_NEWLINE ) ); if( ciBoundEnd == string :: npos ) return 0; strBoundary = strBoundary.substr( 0, ciBoundEnd ); // strBoundary now contains the boundary string :: size_type iContent = cstrPost.find( C_STR_DOUBLE_NEWLINE ); if( iContent == string :: npos ) return 0; iContent += ( sizeof(C_STR_DOUBLE_NEWLINE) - 1 ); const string cstrContent( cstrPost.substr( iContent ) ); // decode CAtomList *pList = new CAtomList( ); CAtomDicti *pSegment = 0; string :: size_type iSegStart = 0; string :: size_type iSegEnd = 0; string :: size_type iDispPrev = 0; string :: size_type iDispPos = 0; CAtomDicti *pDisp = 0; string strSeg = string( ); string strDisp = string( ); string :: size_type iDispStart = 0; string :: size_type iDispEnd = 0; string strCurr = string( ); string :: size_type iSplit = 0; string :: size_type iKeyStart = 0; string strKey = string( ); string strValue = string( ); string :: size_type iDataStart = 0; bool bDoSegmentLoop = true; while( bDoSegmentLoop ) { // segment start iSegStart = cstrContent.find( strBoundary, iSegStart ); if( iSegStart == string :: npos ) return pList; iSegStart += strBoundary.size( ); if( cstrContent.substr( iSegStart, 2 ) == C_STR_SEGSTART ) return pList; iSegStart += ( sizeof(C_STR_SEGSTART) - 1 ); // segment end iSegEnd = cstrContent.find( strBoundary, iSegStart ); if( iSegEnd == string :: npos ) { UTIL_LogPrint( string( gmapLANG_CFG["decode_http_post_end"] + "\n" ).c_str( ) ); delete pList; pList = 0; return 0; } iSegEnd -= ( sizeof(C_STR_SEGEND) - 1 ); // found segment pSegment = new CAtomDicti( ); pList->addItem( pSegment ); // this could do with some serious optimizing... strSeg = cstrContent.substr( iSegStart, iSegEnd - iSegStart ); iDispStart = strSeg.find( C_STR_DISPSTART ); if( iDispStart == string :: npos ) { UTIL_LogPrint( string( gmapLANG_CFG["decode_http_post_notfound"] + "\n" ).c_str( ) ); delete pList; pList = 0; return 0; } iDispStart += ( sizeof(C_STR_DISPSTART) - 1 ); iDispEnd = strSeg.find( C_STR_NEWLINE, iDispStart ); if( iDispEnd == string :: npos ) { UTIL_LogPrint( string( gmapLANG_CFG["decode_http_post_disposition"] + "\n" ).c_str( ) ); delete pList; pList = 0; return 0; } strDisp = strSeg.substr( iDispStart, iDispEnd - iDispStart ); iDispPrev = 0; iDispPos = 0; pDisp = new CAtomDicti( ); pSegment->setItem( "disposition", pDisp ); bool bDoItemLoop = true; while( bDoItemLoop ) { // assume a semicolon indicates the end of the item and will never appear inside the item (probably a bad assumption) iDispPrev = iDispPos; iDispPos = strDisp.find( C_STR_ITEMEND, iDispPos ); if( iDispPos == string :: npos ) { // decode last item iDispPos = strDisp.size( ); } strCurr = strDisp.substr( iDispPrev, iDispPos - iDispPrev ); iSplit = strCurr.find( C_STR_ITEMEQ ); if( iSplit == string :: npos ) { // found a key without value, i.e. "form-data", useless so ignore it if( iDispPos == strDisp.size( ) ) break; // + strlen( ";" ) iDispPos++; continue; } // strip whitespace iKeyStart = strCurr.find_first_not_of( C_STR_WSPACE ); if( iKeyStart == string :: npos || iKeyStart > iSplit ) { UTIL_LogPrint( string( gmapLANG_CFG["decode_http_post_disposition"] + "\n" ).c_str( ) ); delete pList; pList = 0; return 0; } strKey = strCurr.substr( iKeyStart, iSplit - iKeyStart ); strValue = strCurr.substr( iSplit + 1 ); // strip quotes if( strValue.size( ) > 1 && strValue[0] == CHAR_QUOTE ) strValue = strValue.substr( 1, strValue.size( ) - 2 ); pDisp->setItem( strKey, new CAtomString( strValue ) ); if( iDispPos == strDisp.size( ) ) bDoItemLoop = false; // + strlen( ";" ) iDispPos++; } // data iDataStart = strSeg.find( C_STR_DOUBLE_NEWLINE ); if( iDataStart == string :: npos ) { UTIL_LogPrint( string( gmapLANG_CFG["decode_http_post_segment"] + "\n" ).c_str( ) ); delete pList; pList = 0; return 0; } iDataStart += ( sizeof(C_STR_DOUBLE_NEWLINE) - 1 ); pSegment->setItem( "data", new CAtomString( strSeg.substr( iDataStart ) ) ); } // this should never happen, so who cares delete pList; pList = 0; return 0; }