Весь трафик для абонентов Мегалайн бесплатный


Вернуться   Tele-Sat.Ru :: TSR-Team.Ru > Спутниковые и эфирные цифровые технологии > Хитрый просмотр > Шаринг > Протоколы шаринга
Регистрация Чат Аплоад Календарь Поиск Сообщения за день Все разделы прочитаны Правила форума

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
Старый 31.01.2009, 12:54   #1
По умолчанию [Клиент-Сервер] описание NewCamD 5.25

Писано сие творение aiZent-ом, в случае копирования, вы обязаны установить ссылку на эту тему.

Протокол NewCamd использует для транспорта данных сетевой протокол TCP, данные соединения шифруются по алгоритму тройной DES, длина ключа 14 байт (112 бит)

После установления подключения к серверу, клиент получает от сервера 14 случайных байт, эти байты проXORены 3DES ключем из конфиг-файла
Клиент <- Сервер 1/5
шифрование: нет
----------------------------------------------------------
00: 77 9d cc 5d d2 0d 59 2e dc ed b8 17 c1 ab w ] Y.

14 рандомных байт используются для передачи шифрованых логина и пароля.
Все дальнейшие пакеты идут с "префиксом" в 2 байта, в которых указан код команды. Коды команд:

Код:
#define CWS_FIRSTCMDNO 0xe0
typedef enum
{
  MSG_CLIENT_2_SERVER_LOGIN = CWS_FIRSTCMDNO,
  MSG_CLIENT_2_SERVER_LOGIN_ACK,
  MSG_CLIENT_2_SERVER_LOGIN_NAK,
  MSG_CARD_DATA_REQ,
  MSG_CARD_DATA,
  MSG_SERVER_2_CLIENT_NAME,
  MSG_SERVER_2_CLIENT_NAME_ACK,
  MSG_SERVER_2_CLIENT_NAME_NAK,
  MSG_SERVER_2_CLIENT_LOGIN,
  MSG_SERVER_2_CLIENT_LOGIN_ACK,
  MSG_SERVER_2_CLIENT_LOGIN_NAK,
  MSG_ADMIN,
  MSG_ADMIN_ACK,
  MSG_ADMIN_LOGIN,
  MSG_ADMIN_LOGIN_ACK,
  MSG_ADMIN_LOGIN_NAK,
  MSG_ADMIN_COMMAND,
  MSG_ADMIN_COMMAND_ACK,
  MSG_ADMIN_COMMAND_NAK,
  MSG_KEEPALIVE = CWS_FIRSTCMDNO + 0x1d
} net_msg_type_t;
Клиент отсылает пакет с кодом команды MSG_CLIENT_2_SERVER_LOGIN, который содержит имя пользователя и пароль. Имя пользователя должно заканчиваться символом 0x00 (C-String), пароль следует сразу за логином. Пароль шифруется через функцию crypt GLIBC с салтом "$1$abcdefgh$" и также заканчивается 0x00.

Клиент -> Сервер 1/5
шифрование: да, 14 байтами из конфиг файла
----------------------------------------------------------
00: e0 00 29 64 75 6d 6d 79 00 24 31 24 61 62 63 64 )dummy $1$abcd
10: 65 66 67 68 24 6e 70 53 45 54 51 73 72 49 6d 33 efgh$npSETQsrIm3
20: 35 4d 51 66 69 55 49 41 64 6e 2e 00 5MQfiUIAdn.

Шифрование:
char *userpassword="password";
char *passwdcrypt;
passwdcrypt = (uint8*)__md5_crypt(userpassword, "$1$abcdefgh$");
таким вот образом выполняется аналог шифрования md5_crypt GLIB

(когда я реализовывал поддержку newcamd в Borland C++ Builder 6, пришлось соорудить свой аналог md5_crypt из нескольких файлов (под Win функций GlibC увы нет ) кому нужно забираем вложенный файл).
Вложения
Тип файла: rar md5crypt.rar (15.5 Кб, 20 просмотров)
__________________
Хостинг Казахстан/Мегалайн/Костанай, в т.ч. VPS/VDS.
aiZent
Хостер
 
Аватар для aiZent
 
Регистрация: 24.12.2006
Адрес: Кост.область
Сообщений: 2,193
: 289
: 297 (2)
aiZent как роза среди колючекaiZent как роза среди колючекaiZent как роза среди колючек
Отправить сообщение для aiZent с помощью ICQ
Ответить с цитированием aiZent на форуме  
Старый 31.01.2009, 13:32   #2
aiZent инфо
Хостер (2,193)
Репа: 289
 
Аватар для aiZent
Флаг
Топик Стартер По умолчанию

Сервер проверяет логин/пароль, если они верные, то отсылает клиенту пустой пакет с кодом MSG_CLIENT_2_SERVER_LOGIN_ACK, если неверные, то MSG_CLIENT_2_SERVER_LOGIN_NAK. Хотелось бы отметить, если сервер закрывает соединение, ваш DES ключ (14 байт из конфига) неверный, т.к. коды команды с неверным ключем будет испорчены и сервер просто непоймет, что от него хотят
После выполнения авторизации меняется ключ шифрования соединения, 14 байт XORятся шифрованным паролем, назовем его ключ сессии.

Код:
for (i = 0; i < strlen(cryptPw); i++) deskey[i] ^= cryptPw[i];
Клиент <- Сервер 1/5
шифрование: да, 14 байт
----------------------------------------------------------
00: e1 00 00

Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5
__________________
Хостинг Казахстан/Мегалайн/Костанай, в т.ч. VPS/VDS.

aiZent на форуме
Ответить с цитированием
Старый 31.01.2009, 13:41   #3
aiZent инфо
Хостер (2,193)
Репа: 289
 
Аватар для aiZent
Флаг
Топик Стартер По умолчанию

Клиент отсылает серверу пустой пакет с кодом MSG_CARD_DATA_REQ

Клиент -> Сервер 1/5
шифрование: ключ сессии
----------------------------------------------------------
00: e3 00 00

Сервер пересылает на клиент пакет с кодом MSG_CARD_DATA и данными доступных карт

Клиент <- Сервер 1/5
шифрование: ключ сессии
----------------------------------------------------------
00: e4 00 17 01 09 0f 00 00 00 00 XX XX XX XX 01 00 a
10: 00 00 00 00 00 00 XX XX XX 00

байт 1: MSG_CARD_DATA
байт 2/3: длина данных
байт 4: идентификатор пользователя
байт 5/6: CAID
байты 7-14: номер карточки (только для идентификатора пользователя == 1, иначе заполнено 0x00)
байт 15: число провайдеров на карте (nProv)
Код:
for (i = 0; i < nProv; i++)
{
  byte 16+11*i - 18+11*i: IDENT
  byte 19+11*i - 26+11*i: идентификатор провайдера (только для идентификатора пользователя == 1, иначе заполнено 0x00)
}
* небольшое пояснение, мой вариант сервера всегда отправляет
mbuf[3] = item+10; (item порядковый номер клиента)
....
mbuf[6] = 0x00;
mbuf[7] = 0x00;
mbuf[8] = 0x00;
mbuf[9] = 0x00;
mbuf[10] = 0x00;
mbuf[11] = 0x00;
mbuf[12] = 0x00;
mbuf[13] = 0x00;
....
mbuf[18+11*cp] = 0x00;
mbuf[19+11*cp] = 0x00;
mbuf[20+11*cp] = 0x00;
mbuf[21+11*cp] = 0x00;

может это не совсем корректно, но все работает отлично


После того как клиент получил список идентов начинают обрабатываться запросы ECM/EMM.
Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5
__________________
Хостинг Казахстан/Мегалайн/Костанай, в т.ч. VPS/VDS.

aiZent на форуме
Ответить с цитированием
Старый 31.01.2009, 13:44   #4
aiZent инфо
Хостер (2,193)
Репа: 289
 
Аватар для aiZent
Флаг
Топик Стартер По умолчанию

Вот небольшой кусок кода из которого можно выудить все что нужно .
[spoiler]
Код:
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef unsigned long long uint64;

#define CWS_FIRSTCMDNO 0xe0

typedef enum
{
MSG_CLIENT_2_SERVER_LOGIN = CWS_FIRSTCMDNO,
MSG_CLIENT_2_SERVER_LOGIN_ACK,
MSG_CLIENT_2_SERVER_LOGIN_NAK,
MSG_CARD_DATA_REQ,
MSG_CARD_DATA,
MSG_SERVER_2_CLIENT_NAME,
MSG_SERVER_2_CLIENT_NAME_ACK,
MSG_SERVER_2_CLIENT_NAME_NAK,
MSG_SERVER_2_CLIENT_LOGIN,
MSG_SERVER_2_CLIENT_LOGIN_ACK,
MSG_SERVER_2_CLIENT_LOGIN_NAK,
MSG_ADMIN,
MSG_ADMIN_ACK,
MSG_ADMIN_LOGIN,
MSG_ADMIN_LOGIN_ACK,
MSG_ADMIN_LOGIN_NAK,
MSG_ADMIN_COMMAND,
MSG_ADMIN_COMMAND_ACK,
MSG_ADMIN_COMMAND_NAK,
MSG_KEEPALIVE = CWS_FIRSTCMDNO + 0x1d
} net_msg_type_t;

typedef enum
{
COMMTYPE_CLIENT,
COMMTYPE_SERVER
} comm_type_t;

typedef struct customData_struct
{
uint16 sid;
} customData_t;

void des_key_parity_adjust(uint8 *key, uint8 len)
{
uint8 i, j, parity;

for (i = 0; i < len; i++)
{
parity = 1;
for (j = 1; j < 8; j++) if ((key[i] >> j) & 0x1) parity = ~parity & 0x01;
key[i] |= parity;
}
}

uint8 *des_key_spread(uint8 *normal)
{
static uint8 spread[16];

spread[ 0] = normal[ 0] & 0xfe;
spread[ 1] = ((normal[ 0] << 7) | (normal[ 1] >> 1)) & 0xfe;
spread[ 2] = ((normal[ 1] << 6) | (normal[ 2] >> 2)) & 0xfe;
spread[ 3] = ((normal[ 2] << 5) | (normal[ 3] >> 3)) & 0xfe;
spread[ 4] = ((normal[ 3] << 4) | (normal[ 4] >> 4)) & 0xfe;
spread[ 5] = ((normal[ 4] << 3) | (normal[ 5] >> 5)) & 0xfe;
spread[ 6] = ((normal[ 5] << 2) | (normal[ 6] >> 6)) & 0xfe;
spread[ 7] = normal[ 6] << 1;
spread[ 8] = normal[ 7] & 0xfe;
spread[ 9] = ((normal[ 7] << 7) | (normal[ 8] >> 1)) & 0xfe;
spread[10] = ((normal[ 8] << 6) | (normal[ 9] >> 2)) & 0xfe;
spread[11] = ((normal[ 9] << 5) | (normal[10] >> 3)) & 0xfe;
spread[12] = ((normal[10] << 4) | (normal[11] >> 4)) & 0xfe;
spread[13] = ((normal[11] << 3) | (normal[12] >> 5)) & 0xfe;
spread[14] = ((normal[12] << 2) | (normal[13] >> 6)) & 0xfe;
spread[15] = normal[13] << 1;

des_key_parity_adjust(spread, 16);
return spread;
}

void des_random_get(uint8 *buffer, uint8 len)
{
uint8 idx = 0;
int randomNo = 0;

for (idx = 0; idx < len; idx++)
{
if (!(idx % 3)) randomNo = rand();
buffer[idx] = (randomNo >> ((idx % 3) << 3)) & 0xff;
}
}

int des_encrypt(uint8 *buffer, int len, uint8 *deskey)
{
uint8 checksum = 0;
uint8 noPadBytes;
uint8 padBytes[7];
char ivec[8];
uint16 i;

if (!deskey) return len;
noPadBytes = (8 - ((len - 1) % ) % 8;
if (len + noPadBytes + 1 >= CWS_NETMSGSIZE-8) return -1;
des_random_get(padBytes, noPadBytes);
for (i = 0; i < noPadBytes; i++) buffer[len++] = padBytes[i];
for (i = 2; i < len; i++) checksum ^= buffer[i];
buffer[len++] = checksum;
des_random_get((uint8 *)ivec, ;
memcpy(buffer+len, ivec, ;
for (i = 2; i < len; i +=
{
cbc_crypt(deskey , (char *) buffer+i, 8, DES_ENCRYPT, ivec);
ecb_crypt(deskey+8, (char *) buffer+i, 8, DES_DECRYPT);
ecb_crypt(deskey , (char *) buffer+i, 8, DES_ENCRYPT);
memcpy(ivec, buffer+i, ;
}
len += 8;
return len;
}

int des_decrypt(uint8 *buffer, int len, uint8 *deskey)
{
char ivec[8];
char nextIvec[8];
int i;
uint8 checksum = 0;

if (!deskey) return len;
if ((len-2) % 8 || (len-2) < 16) return -1;
len -= 8;
memcpy(nextIvec, buffer+len, ;
for (i = 2; i < len; i +=
{
memcpy(ivec, nextIvec, ;
memcpy(nextIvec, buffer+i, ;
ecb_crypt(deskey , (char *) buffer+i, 8, DES_DECRYPT);
ecb_crypt(deskey+8, (char *) buffer+i, 8, DES_ENCRYPT);
cbc_crypt(deskey , (char *) buffer+i, 8, DES_DECRYPT, ivec);
}
for (i = 2; i < len; i++) checksum ^= buffer[i];
if (checksum) return -1;
return len;
}

uint8 *des_login_key_get(uint8 *key1, uint8 *key2)
{
uint8 des14[14];
static uint8 des16[16];
int i;

for (i = 0; i < 14; i++) des14[i] = key1[i] ^ key2[i];
memcpy(des16, des_key_spread(des14), 16);
return des16;
}

int network_message_send(int handle, uint16 *netMsgId, customData_t *customData, uint8 *buffer, int len, uint8 *deskey, comm_type_t commType)
{
uint8 netbuf[CWS_NETMSGSIZE];

if (len < 3 || len + 12 > CWS_NETMSGSIZE || handle < 0) return -1;
buffer[1] = (buffer[1] & 0xf0) | (((len - 3) >> & 0x0f);
buffer[2] = (len - 3) & 0xff;
memcpy(netbuf+12, buffer, len);
len += 12;
if (netMsgId) { if (commType == COMMTYPE_CLIENT) (*netMsgId)++; netbuf[2] = (*netMsgId) >> 8; netbuf[3] = (*netMsgId) & 0xff; }
else netbuf[2] = netbuf[3] = 0;
if (customData)
{
netbuf[4] = customData->sid >> 8;
netbuf[5] = customData->sid & 0xff;
memset(netbuf+6, 0, 6);
}
else memset(netbuf+4, 0, ;
if ((len = des_encrypt(netbuf, len, deskey)) < 0) return -1;
netbuf[0] = (len - 2) >> 8;
netbuf[1] = (len - 2) & 0xff;
write(handle, netbuf, len);
return 0;
}

int network_message_receive(int handle, uint16 *netMsgId, customData_t *customData, uint8 *buffer, uint8 *deskey, comm_type_t commType)
{
int len;
uint8 netbuf[CWS_NETMSGSIZE];
int returnLen;

if (customData) memset(customData, 0, sizeof(customData_t));
if (!buffer || handle < 0) return -1;
len = read(handle, netbuf, 2);
if (!len) return 0;
if (len != 2) return -1;
if (((netbuf[0] << | netbuf[1]) > CWS_NETMSGSIZE - 2) return -1;
len = read(handle, netbuf+2, (netbuf[0] << | netbuf[1]);
if (!len) return 0;
if (len != ((netbuf[0] << | netbuf[1])) return -1;
len += 2;
if ((len = des_decrypt(netbuf, len, deskey)) < 15) return -1;
if ((returnLen = (((netbuf[13] & 0x0f) << | netbuf[14]) + 3) > len-12) return -1;
if (netMsgId)
{
switch (commType)
{
case COMMTYPE_SERVER:
*netMsgId = (netbuf[2] << | netbuf[3];
break;

case COMMTYPE_CLIENT:
if (*netMsgId != ((netbuf[2] << | netbuf[3])) return -1;
break;

default:
return -1;
break;
}
}
if (customData)
{
customData->sid = (netbuf[4] << | netbuf[5];
}
memcpy(buffer, netbuf+12, returnLen);
return returnLen;
}

void network_cmd_no_data_send(int handle, uint16 *netMsgId, customData_t *customData, net_msg_type_t cmd, uint8 *deskey, comm_type_t commType)
{
uint8 buffer[CWS_NETMSGSIZE];

buffer[0] = cmd; buffer[1] = 0;
network_message_send(handle, netMsgId, customData, buffer, 3, deskey, commType);
}

int network_cmd_no_data_receive(int handle, uint16 *netMsgId, customData_t *customData, uint8 *deskey, comm_type_t commType)
{
uint8 buffer[CWS_NETMSGSIZE];

if (network_message_receive(handle, netMsgId, customData, buffer, deskey, commType) != 3) return -1;
return buffer[0];
}

int network_tcp_incoming_port_open(uint16 port)
{
struct sockaddr_in socketAddr;
int socketOptActive = 1;
int handle;

if (!port) return -1;

if ((handle = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
fprintf(stderr, "network port %u open: ", port);
perror("socket");
return -1;
}

if (setsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &socketOptActive, sizeof(int)) < 0)
{
fprintf(stderr, "network port %u open: error setsockoptn", port);
close(handle);
return -1;
}

socketAddr.sin_family = AF_INET;
socketAddr.sin_port = htons(port);
socketAddr.sin_addr.s_addr = htonl(INADDR_ANY);

if (bind(handle, (struct sockaddr *) &socketAddr, sizeof (socketAddr)) < 0)
{
fprintf(stderr, "network port %u open: ", port);
perror("bind");
close(handle);
return -1;
}

if (listen(handle, 5) < 0)
{
fprintf(stderr, "network port %u open: ", port);
perror("listen");
close(handle);
return -1;
}
return handle;
}

int network_tcp_connection_accept(int socketHandle)
{
int connHandle;
struct sockaddr_in peerAddr;
struct sockaddr_in myAddr;
socklen_t peerAddrLen;
socklen_t myAddrLen;
uint16 peerPort, myPort;
uint32 peerIp, myIp;

if (socketHandle < 0) return -1;
peerAddrLen = sizeof(peerAddr);
myAddrLen = sizeof(myAddr);
if ((connHandle = accept(socketHandle, (struct sockaddr *) &peerAddr, &peerAddrLen)) < 0) { fprintf(stderr, "error network accept connectionn"); return -1; }
peerPort = ntohs(peerAddr.sin_port);
peerIp = ntohl(peerAddr.sin_addr.s_addr);
myPort = ntohs(myAddr.sin_port);
myIp = ntohl(myAddr.sin_addr.s_addr);

/* optional: do checks on or log IP of incoming connections */

return connHandle;
}

int network_tcp_connection_open(uint8 *hostname, uint16 port)
{
int handle;
struct hostent *hostaddr;
struct sockaddr_in socketAddr;

if (!(hostaddr = gethostbyname(hostname))) { fprintf(stderr, "Host lookup of %s failedn", hostname); return -1; }
if ((handle = socket(PF_INET, SOCK_STREAM, 0)) < 0) { fprintf(stderr, "network make connection: couldn't create socketn"); return -1; }
socketAddr.sin_family = AF_INET;
socketAddr.sin_port = htons(port);
socketAddr.sin_addr.s_addr = ((struct in_addr *)hostaddr->h_addr)->s_addr;
if (connect(handle, (struct sockaddr *)&socketAddr, sizeof(socketAddr)) < 0) { fprintf(stderr, "network make connection: error connectn"); close(handle); return -1; }
return handle;
}
[/spoiler]
Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5

Основные команды запроса/ответа ECM/DW опишу чуть позже, к клиентам надо ехать .
Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5
__________________
Хостинг Казахстан/Мегалайн/Костанай, в т.ч. VPS/VDS.

aiZent на форуме
Ответить с цитированием
Эти 5 пользователя(ей) сказали Спасибо aiZent за это полезное сообщение:
dimmck (31.01.2009), sat-35 (02.02.2009), sergiuss (01.02.2009), slav0n (06.02.2009), valik55 (25.10.2009)
Старый 27.03.2009, 08:46   #5
Igorkn инфо
Гость (n/a)

 
Аватар для Igorkn
По умолчанию

Возможно ли сделать шаринг-сервер так чтобы он мог из какого-нибудь softcam.key брать ключи biss и отправлять их клиенту. Есть сервер c DVB платами вещающий каналы в небольшую локальную сеть, на нем установлено клиентское ПО для шаринга по протоколу newcamd, соответственно для каждого канала свой логин пароль. Т.к. biss не работает через шаринг то проблема с открытием каналов в данной кодировке.

Ответить с цитированием
Старый 27.03.2009, 11:59   #6
aiZent инфо
Хостер (2,193)
Репа: 289
 
Аватар для aiZent
Флаг
Топик Стартер По умолчанию

Ну по идее biss это даже не кодировка, кодировка CSA, а так называемый BISS это просто DW (половинка) в открытом виде, соответственно, с таким же успехом можно посылать постоянно одну и ту же DW-ку, трудность в том, как определить DW для какого канала нужно посылать? Никогда не интересовался, летят ли ECM для каналов кодированных в "BISS", если не летят, тогда уже будет проблемно.

p.s. Итог: Написать сервер несложно, можно даже сделать чтобы с каждого отдельного порта отдавалась только одна DW-ка (каждый канал на отдельном порте), другое дело как заставить ресивер выполнить запрос DW-ки
__________________
Хостинг Казахстан/Мегалайн/Костанай, в т.ч. VPS/VDS.

aiZent на форуме
Ответить с цитированием
Этот пользователь сказал Спасибо aiZent за это полезное сообщение:
dimmck (27.03.2009)
Старый 04.06.2009, 03:06   #7
Horitonov инфо
Новичок (9)
Репа: 11
 
Аватар для Horitonov
По умолчанию

Хорошая статья ! но плохо что нету продолжения .
Интересно юзеры сверяются с базой , а вот с какой ? можно же прописать в ТХТ , а можно и в MySQL .

Horitonov вне форума
Ответить с цитированием
Старый 04.06.2009, 10:21   #8
aiZent инфо
Хостер (2,193)
Репа: 289
 
Аватар для aiZent
Флаг
Топик Стартер По умолчанию

А это уже как реализуешь
[spoiler]
хорошо быть программером, можно сделать так, или эдак, короч так как хочешь )
[/spoiler]
__________________
Хостинг Казахстан/Мегалайн/Костанай, в т.ч. VPS/VDS.

aiZent на форуме
Ответить с цитированием
Старый 04.06.2009, 17:59   #9
Horitonov инфо
Новичок (9)
Репа: 11
 
Аватар для Horitonov
По умолчанию

Ясно , плохо что весь код на С++ так как начал изучать Делфи уже купил пару книг сижу и читаю .
aiZent опиши основные команды запроса/ответа ECM/DW

Horitonov вне форума
Ответить с цитированием
Старый 04.06.2009, 21:35   #10
aiZent инфо
Хостер (2,193)
Репа: 289
 
Аватар для aiZent
Флаг
Топик Стартер По умолчанию

[spoiler]
Весь код на С/С++ ну может быть еще Java (если после последних событий (лицензирование эффективного сборщика мусора) не сдохнет) и будет в будущем, за Delphi только островки коммьюнити останутся ) борланд практически умер.
А С/С++ отраслевой стандарт .
[/spoiler]
Цитата:
Сообщение от Horitonov;undefined
основные команды запроса/ответа ECM/DW
В протоколе Newcamd?
__________________
Хостинг Казахстан/Мегалайн/Костанай, в т.ч. VPS/VDS.

aiZent на форуме
Ответить с цитированием
Ответ

Закладки

Метки
oscam, было, дать, дельфи, _http

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход



Часовой пояс GMT +4, время: 08:51.

Работает на vBulletin®.
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Перевод: zCarot