Забытый протокол от AOL Вольф Данияр Спецвыпуск: Хакер, номер #058, стр. 058-078-6 if( recv(sock, buffer, 2048, 0) == -1 ){perror("RECV"); close(sock);} Условие на наличие входящего сообщения. В условии используется логическое "И". Первое выражение в if - это наличие аргумента DATA(0x02) в FLAP. Во втором выражении сверяются первые пять символов, после флэп-заголовка(6 bytes), IM_IN – входящее сообщение. Если проверка подтвердится, то входящая строка попадает в тело условия. if( (*((u_int8_t *)(buffer+1)) == 0x02) && (!memcmp(buffer+6, "IM_IN", 5) ) ) { /* После того как строка попала в тело условия, из нее выделяются ICQ/AIM(screenname) и сообщение. */ screenlen = 0; Отсчитываем 12 байт от начала пакета TOC(AIM), чтобы определить ICQ/screenname-отправителя сообщения, сохраняем его в переменной remscreenname. address = (buffer+12); while(*address != '\x3A') { remscreenname[screenlen] = (*address); screenlen++; address++; } Отделяем текстовое сообщение из входящего пакета и записываем его в аргумент messaga: address++; i=0; i=ntohs(*((u_int16_t *)(buf+4))); i=i-6-screenlen-1; memset(messaga, 0, 128); memcpy(messaga, address, i); ... Выводим входящие ICQ/screename и текст сообщения на стандартный вывод: printf("%s -> %s\n", remscreenname, messaga); } } // Закрываем тело цикла входящих сообщений. ... } // Здесь заканчивается код главной функции main. //Функции для формирования AIM-протокола. /* Формируем ответ серверу на FLAP SIGON. В полезном грузе будет значение 0x00000001, 0x0001, длина UIN и сам UIN. */ static char *encode_flapsigon(char *buf, const char *screenname) { char *sflap; /* Пропускаем поле Data Length и ставим на него указатель, дабы позже заполнить его. */ buf=sflap=flap_begin(buf, TYPE_SIGNON); buf=writel(buf, 0x00000001); buf=writew(buf, 0x0001); buf=writew(buf, strlen(screenname)); buf=writes(buf, screenname, strlen(screenname)); //подсчитываем длину пакета и вписываем его в поле Data Length flap_end(buf, sflap); return buf; } /* Криптуем наш пароль (просто xor'ируем его), в виде начальных данных, необходимых для шифрования, берем строку "Tic/Toc", после чего получим ключ: */ static unsigned char *roast_password(const char *pass) { static unsigned char rp[256]; static char *roast = ROAST; int pos = 2; int x; strcpy(rp, "0x"); for (x = 0; (x < 150) && pass[x]; x++) pos += sprintf(&rp[pos], "%02x", pass[x] ^ roast[x % strlen(roast)]); rp[pos] = '\0'; return rp; } /* Функция конструирует пакет, с помощью которого будем проходить аутентификацию. */ static char *encode_toc_signon(char *buf, const char *screenname, const char *password) { char *sflap; char *data; data=(char *)malloc(256*sizeof(char *)); memset(data, 0, 256); buf=sflap=flap_begin(buf, TYPE_DATA); sprintf(data, "toc_signon %s %d %s %s %s \"%s\"",AUTH_HOST, AUTH_PORT, screenname, roast_password(password), LANGUAGE, REVISION); buf=writes(buf, data, strlen(data)); buf=writeb(buf, 0x00); flap_end(buf, sflap); free(data); return buf; } /* Функция по формированию пакета сообщений (текст). Аргументы функции - это выделенный буфер в памяти buf, ICQ/AIM(screenname)-адресата и текстовое сообщение mess. |