Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Сети > соединение с IRC через SOCKS-5


Автор: barberan 28.4.2007, 11:54

Вот таким кодом хотел соединиться и оставить сообщение на канале IRC сервера через СОКС-5. НО, почему-то ошибка...
Код

#include <stdio.h>
#include <stdlib.h>

#include <winsock2.h>
#include <windows.h>
#include "resource.h"

#pragma comment(lib,"ws2_32.lib")

//--------------------------------------------------
struct server
{
    char address[32];
    unsigned short port;
};
int ConnectSocks(SOCKET sock, server *i,server *s)
{
    WSAData wsa;
    WSAStartup(MAKEWORD(2,2),&wsa);

    SOCKADDR_IN sin;
    memset(&sin,0,sizeof(sin));

    char req[256];
    char ans[1024];
    int n = 0;

    if( (strlen(s->address)!= 0) && (s->port != 0))
    {
        sin.sin_addr.S_un.S_addr = inet_addr(s->address);
        sin.sin_family = AF_INET;
        sin.sin_port = htons(s->port);
    }
    else
        return 1;

    sock = socket(AF_INET,SOCK_STREAM,0);
    if(sock != INVALID_SOCKET)
    {
        if(!connect(sock,(struct sockaddr*)&sin,sizeof(sin)))
        {
            req[0] = 5;
            req[1] = 1;
            req[2] = 0;
            n = send(sock,req,3,0);
            if(n==0) return 1;

            n = recv(sock,ans,2,0);
            if(n != 2) return 1;
            if(ans[1] !=0) return 1;

            int m = strlen(i->address);
            req[0] = 5;
            req[1] = 1;
            req[2] = 0;
            req[3] = 3;
            req[4] = m;
            memcpy(req+5,i->address,m);
            *((unsigned short*)(req+5+m)) = htons(i->port);
            n = send(sock,req,m+7,0);
            if(n==0) return 1;
            n = recv(sock,ans,10,0);
            if(n != 10) return 1;
            if(ans[1] != 0) return 1; //<--- !!!!здесь почему-то выходим с ошибкой!!!
            if(ans[3] != 1) return 1;
        }
        else
        {
            MessageBox(HWND_DESKTOP,"Connection failed","",MB_ICONERROR);
            return 1;
        }
    }

    return 0;
}
int WINAPI WinMain(HINSTANCE hi,HINSTANCE,LPSTR,int)
{
    char *socks_address = "71.76.209.206";
    int socks_port = 30027;

    char *irc_address = "80.92.100.184"; //80.92.100.184
    int irc_port = 6667;
    //------------------------------

    server irc = {0};
    server socks = {0};
    SOCKET s = INVALID_SOCKET;
    char tmp[256];

    wsprintf(socks.address,"%s",socks_address);
    socks.port = socks_port;

    wsprintf(irc.address,"%s",irc_address);
    irc.port = irc_port;

    if( ConnectSocks(s,&irc,&socks) == 1)
    return 0;
    else
    {
        wsprintf(tmp,"PASS %s\r\n","password");
        send(s,tmp,strlen(tmp)+1,0);
        wsprintf(tmp,"NICK %s\r\n","thriouss");
        send(s,tmp,strlen(tmp)+1,0);
        wsprintf(tmp,"USER ID 127.0.0.1 Server :%s\r\n","username");
        send(s,tmp,strlen(tmp)+1,0);
        wsprintf(tmp,"JOIN #%s\r\n","development");
        send(s,tmp,strlen(tmp)+1,0);
        wsprintf(tmp,"PRIVMSG #%s :\x03\x32 %s \r\n","development","message");
        send(s,tmp,strlen(tmp)+1,0);
    }
    return 0;
}


помогите разобраться, плз,спс.

Автор: ptr 28.4.2007, 13:10
Цитата(barberan @  28.4.2007,  14:54 Найти цитируемый пост)
if(ans[1] != 0) return 1; //<--- !!!!здесь почему-то выходим с ошибкой!!!

И с какой же ошибкой?

Автор: GremlinProg 28.4.2007, 16:24
а вообще ты уверен, что порт SOCKS5 - это 30027?
Обычно он работает на порту 1080.

Добавлено через 5 минут и 36 секунд
Цитата(ptr @  28.4.2007,  15:10 Найти цитируемый пост)
И с какой же ошибкой? 

это ошибка авторизации сервера, в этом месте он должен прислать ответ, что такой вот мол метод поддерживается. Первый байт ответа - нгомер версии, а второй - номер метода, если номер метода равен 255, значит ни один из предложенных методов  авторизации не поддерживается, но по ходу, у тебя даже до этого не доходит, проверь все же порт.

Автор: GremlinProg 28.4.2007, 16:42
Цитата(barberan @  28.4.2007,  13:54 Найти цитируемый пост)
if(ans[1] !=0) return 1;

ясно, короче ты хочешь приконнектишься к серваку, у которого нет авторизации, а у твоего - есть, вот он и выходит.
Цитата

          X'00' аутентификация не требуется
          X'01' GSSAPI
          X'02' USERNAME/PASSWORD (см. RFC1929)
          X'03' до X'7F' зарезервировано IANA 
          X'80' до X'FE' преднозначено для частных методов
          X'FF' нет применимых методов

посмотри, какой из них возвращает сервер и используй защищенный вход.

Автор: ptr 28.4.2007, 17:15
Цитата(GremlinProg @  28.4.2007,  19:24 Найти цитируемый пост)
это ошибка авторизации сервера, в этом месте он должен прислать ответ, что такой вот мол метод поддерживается. Первый байт ответа - нгомер версии, а второй - номер метода, если номер метода равен 255, значит ни один из предложенных методов  авторизации не поддерживается, но по ходу, у тебя даже до этого не доходит, проверь все же порт.

Я в курсе кто кому что шлёт. Авторизация у него проходит нормально (строки 48-50), а вот на запрос сервер возвращает ошибку, вот эту то ошибку я и хотел узнать.

Автор: GremlinProg 28.4.2007, 17:49
ptr, я же сказал:
Цитата(GremlinProg @  28.4.2007,  18:42 Найти цитируемый пост)
ты хочешь приконнектишься к серваку, у которого нет авторизации, а у твоего - есть, вот он и выходит.

сервер ни какой ошибки не шлет, просто клиент не работает с запароленным сервером, об этом говорит как раз 50-я строка.

Добавлено через 3 минуты и 32 секунды
это у него функция возвращает 1, т.е. ошибка, которую он анализирует в 96 строке.

Автор: barberan 28.4.2007, 22:06
if(ans[1] != 0) return 1; //<--- !!!!здесь почему-то выходим с ошибкой!!!

У меня там не НОЛЬ, а ЕДИНИЦА... в этом-то и вся суть... и что-же делать? 

Автор: GremlinProg 28.4.2007, 22:17
не должно там быть единицы, потому что запрос идет для нуля(то бишь без пароля):
Цитата(barberan @  28.4.2007,  13:54 Найти цитируемый пост)
            req[0] = 5;
            req[1] = 1;
            req[2] = 0;

т.е. ответ может быть только 255 или 0 третьего не дано
поставь ноль

Добавлено @ 22:19
либо установи req[2] = 1 и читай вот это: http://www.faqs.org/faqs/kerberos-faq/general/section-84.html

Автор: barberan 29.4.2007, 09:47
Если req[2] =1, то там ведь еще пол кода переписывать???

Автор: GremlinProg 29.4.2007, 10:18
конечно, потому ссылку и дал

Автор: ptr 29.4.2007, 14:26
Цитата(GremlinProg @  28.4.2007,  20:49 Найти цитируемый пост)
сервер ни какой ошибки не шлет, просто клиент не работает с запароленным сервером, об этом говорит как раз 50-я строка.

Цитата(GremlinProg @  29.4.2007,  01:17 Найти цитируемый пост)
не должно там быть единицы, потому что запрос идет для нуля(то бишь без пароля):
т.е. ответ может быть только 255 или 0 третьего не дано
поставь ноль


GremlinProg, открой глаза и внимательно посмотри на код. Ошибка авторизации должна возникать в 50 строке, а у него в 64 (разница надеюсь заметна)! С 42 по 50 он посылает запрос и принимает ответ на авторизацию (тут всё нормально). Дальше он формирует и отсылает CONNECT-пакет и только потом от сервера приходит ошибка general failure(1).

Цитата(barberan @  29.4.2007,  12:47 Найти цитируемый пост)
Если req[2] =1, то там ведь еще пол кода переписывать???

Не надо особо ничего переписывать (если авторизацию добавлять не хочешь). Надо добавить функции по приёму/отсылке всего буфера и изменить

Код

int ConnectSocks(SOCKET sock, server *i,server *s)

на
Код

int ConnectSocks(SOCKET &sock, server *i,server *s)


И смени SOCKS сервер на другой.


Автор: GremlinProg 29.4.2007, 15:16
ptr, ты прав, так и есть, невнимательно смотрел, молодец, что поправил, а я думаю, чо barberan про единицу говорит. Тогда запрос нормальный, а вот с ответом, действительно непонятно, нужно проверить какой код ошибки присылает сервер:
Цитата

             X'00' успешный
             X'01' ошибка SOCKS-сервера
             X'02' соединение запрещено набором правил
             X'03' сеть недоступна
             X'04' хост недоступен
             X'05' отказ в соединении
             X'06' истечение TTL
             X'07' команда не поддерживается
             X'08' тип адреса не поддерживается
             X'09' до X'FF' не определены

barberan поставь брекпойнт на 64 строку и посмотри содержимое ans[1], она может быть восьмой, тогда нужно будет вместо домена, конкретно, IP адрес писать.

Добавлено через 7 минут и 48 секунд
Цитата(ptr @  29.4.2007,  16:26 Найти цитируемый пост)
SOCKET &sock

зачем?

Автор: ptr 29.4.2007, 16:35
Цитата(GremlinProg @  29.4.2007,  18:16 Найти цитируемый пост)
barberan поставь брекпойнт на 64 строку и посмотри содержимое ans[1], она может быть восьмой, тогда нужно будет вместо домена, конкретно, IP адрес писать.


Цитата(barberan @  29.4.2007,  01:06 Найти цитируемый пост)
У меня там не НОЛЬ, а ЕДИНИЦА... в этом-то и вся суть... и что-же делать? 


Цитата(GremlinProg @  29.4.2007,  18:16 Найти цитируемый пост)
зачем?

Для последующего использования сокета в строках 100-109.

Кстати на других SOCKS серверах работает нормально.

Автор: GremlinProg 29.4.2007, 16:55
Цитата(ptr @  29.4.2007,  18:35 Найти цитируемый пост)
Для последующего использования сокета в строках 100-109

согласен
Цитата(barberan @  29.4.2007,  00:06 Найти цитируемый пост)
У меня там не НОЛЬ, а ЕДИНИЦА

а вот это все таки непонятно, в 64 строке байт должен сравниваться с нулем. 0 - значит все Ок.
Цитата(ptr @  29.4.2007,  16:26 Найти цитируемый пост)
Надо добавить функции по приёму/отсылке всего буфера

тут не обязательно он запрашивает конкретно ipv4 адрес для бинда (см. 65 стр)

Автор: ptr 30.4.2007, 07:41
Цитата(GremlinProg @  29.4.2007,  19:55 Найти цитируемый пост)
а вот это все таки непонятно, в 64 строке байт должен сравниваться с нулем. 0 - значит все Ок.


Код

if(ans[1] != 0) return 1; //<--- !!!!здесь почему-то выходим с ошибкой!!!


Цитата(GremlinProg @  29.4.2007,  19:55 Найти цитируемый пост)
тут не обязательно он запрашивает конкретно ipv4 адрес для бинда (см. 65 стр)

В смысле? Я про то, что recv/send не отсылает/принимает весь буфер.

Автор: barberan 30.4.2007, 17:44
GremlinProg, 
"а вот это все таки непонятно, в 64 строке байт должен сравниваться с нулем. 0 - значит все Ок.", У меня там не НОЛЬ, а единица => не все в порядке..

Добавлено через 7 минут и 10 секунд
ptr, Какую-какую функцию добавить??? (Не надо особо ничего переписывать (если авторизацию добавлять не хочешь). Надо добавить функции по приёму/отсылке всего буфера и изменить)

Автор: ptr 2.5.2007, 14:15
Например (взято http://www.rsdn.ru/article/unix/sockets.xml):
Код

int sendall(int s, char *buf, int len, int flags)
{
    int total = 0;
    int n;

    while(total < len)
    {
        n = send(s, buf+total, len-total, flags);
        if(n == -1) { break; }
        total += n;
    }

    return (n==-1 ? -1 : total);
}


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)