protokól gg

0

Witam,
Mam pytanie odnośnie protokołu gg , czy jeśli tą strukturę do logowania się wyślę np źle "wypełnioną"( w sensie jakieś bity w polach po zmieniam czy np błędnie wersje gg podam to czy od serwera otrzymam jakąś odpowiedź o błedzie czy po prostu nic nie otrzymam - pytam się , gdyż wydaje mi się, że wysyłam paczki do serwera gg z numerem gg itp( --ziarno jakoś wcześniej odbieram) ,ale nie otrzymuje żadnej odpowiedzi od serwera.(korzystam z wxWidgets ( wxSocketClient z metody Write do wysyłania )
z góry dziękuję za pomoc ( jak trzeba będzie to wkleję kod);

0

Jakąś odpowiedź powinieneś dostać. Według tego powinno być GG_LOGIN80_OK lub GG_LOGIN_FAILED.

0

Sprawdziłem paczki snifferem i to wygląda w ten sposób że gdy wysyłam ten gg_header z informacją że zaraz wyśle paczkę z numerem gg itp serwer zwraca pusty pakiet( chyba tak jak powinno być) potem wysyłam tą paczkę i wtedy otrzymuje dwa pakiety kolejny pusty i jeszcze jeden z flaga FIN(zamyka połączenie). Czy to oznacza ze mam źle wypełniona structurę gg_login??- tak mi się wydaje, chcę tylko upwenić

0

to wygląda w ten sposób że gdy wysyłam ten gg_header z informacją że zaraz wyśle paczkę z numerem gg
Nie rozumiem, jaki pakiet? Po połączeniu powinieneś odebrać GG_WELCOME z seedem, a później wysłać GG_LOGIN80 i czekać na GG_LOGIN80_OK/GG_LOGIN_FAILED (w każdym razie tak rozumiem opis protokołu).

0

Przepraszam że pisze 2 posty pod rząd , ale
już nie wiem czy ja coś źle w wxWidgets pisze czy to wina żle działajacej struktury
więć tu jest mały wycinek kodu ( z serwerm http sie łacze, pózniej odbieram seed i jest ok ale przy logowaniu jest problem nie wiem gdzie-zamiast otrzymać choćby informacje o nie zalogowaniu się dostaje pustą paczke):

struct gg_login80 {
        int uin;              /* numer Gadu-Gadu */
        char language[2];     /* język: "pl" */
        char hash_type;       /* rodzaj funkcji skrótu hasła */
        char hash[64];        /* skrót hasła dopełniony \0 */
        int status;           /* początkowy status połączenia */
        int flags;            /* flagi (przeznaczenie nieznane) */
        int features;         /* opcje protokołu (0x00000007)*/
        int local_ip;         /* lokalny adres połączeń bezpośrednich (nieużywany) */
        short local_port;     /* lokalny port połączeń bezpośrednich (nieużywany) */
        int external_ip;      /* zewnętrzny adres (nieużywany) */
        short external_port;  /* zewnętrzny port (nieużywany) */
        char image_size;      /* maksymalny rozmiar grafiki w KB */
        char unknown2;        /* 0x64 */
        int version_len;      /* długość ciągu z wersją (0x21) */
        char version[0x21];       /* "Gadu-Gadu Client build 8.0.0.7669" (bez \0) */
        int description_size; /* rozmiar opisu */

};
	//parensacie wierszy wyżej^^^^^

		wxString temp=WxEdit2->GetValue(); ///<- tu jest hasło 
            int hash=this->gg_login_hash((char*)temp.mb_str(wxConvUTF8),welcome.seed);

  
            //2) wypełnianie paczki

            gg_login80 gg_login={wxAtoi( WxEdit1->GetValue() ),'p',GG_LOGIN_HASH_GG32,'0',GG_STATUS_AVAIL,0,0x00000007,0,0,0,0,0x64,0,0x21,'G',0};;
          
           char* ee="Gadu-Gadu Client build 8.0.0.7669";
           wxString t2 = wxString::Format(wxT("%d"),hash);
            strcpy(gg_login.hash, (const char*) t2.mb_str(wxConvUTF8)  );
            strcpy(gg_login.version, ee);
            gg_login.language[1]='l';


            header=new gg_header;
            header->type=GG_LOGIN80;
            header->length = sizeof(gg_login);
            this->connection->Write(header, sizeof(*header));
            this->connection->Write(&gg_login,header->length);

            header=new gg_header;
            this->connection->Read(header,sizeof(*header));

            if(header->type == GG_LOGIN80_OK ) wxMessageBox("zalogowano");  else if(header->type ==GG_LOGIN_FAILED)wxMessageBox("Nie zalogowano");  else wxMessageBox("nie wiem");

Prosze o pomoc, z góry dzięki :)

0

dostaje pustą paczke

Pustą paczkę czyli co?


PS 1. przy GG_LOGIN80_OK powinieneś odebrać gg_login80_ok.
PS 2. zakładam, że sockety masz ustawione na wxSOCKET_WAITALL.

0

pusta paczka czyli buffer jest pusty ale jak snifferem sprawdzam to otrzymuje paczki/pakiety (tcp/ip czyli ten cały header tcp (odsyłam do wikipedii) ale o wartosci 0000=> czyli buffer jest pusty)

0

Hmm, jeśli przerywa ci połączenie, to z dużym prawdopodobieństwem masz coś nie tak z tą strukturą. Czy aby na pewno gg_login80 (i całą reszta) jest wyrównana do jednego bajta?

0

Mnie tez się tak wydaje , Już nie wiem może źle konwertuje dane wxWidgetsowe;, jeśli mógłby ktoś sprawdzić(czyt. porównać ze specyfikacja protokołu) czy dobrze to robię byłbym wdzięczny

0

Pytałem się, czy wszystkie struktury gg_xxx masz wyrównane do jednego bajta. Jeśli nie wiesz o co pytam, patrz 1.1. Format pakietów i konwencje.

Bez odpowiedzi na to pytanie nie ma sensu dalej drążyć tego tematu.

0

Więc, po piwersze korzystam z architektury i386, więc to i tak nic nie zmienia, ale dodałem te makra co tam były podane dla gcc( korzystam z wxDev-cpp), niestety to nic nie zmieniło to musi być coś ze źle wypełniona strukturą. Próbowałem juz na kilka sposobów hash wpisywać do struktury, za każdym razem gdy wypisywałem strukturę wszystko wszytskie pola były takie jak wpisałem( łącznie '\0' na koncu, tam gdzie trzeba), jakby ktoś mógł przeanalizować te moje konwersje z wxWidgets na char itp bo tu może być chyba błąd , jak to nie to, to juz nie mam zielonego pojęcia.

0

Jeśli nie jesteś pewien co do wyrównania struktur, weź zobacz ile wynosi sizeof(gg_login80). Wartość powinna być dokładnie taka, jak suma wielkości wszystkich pól struktury. Jeśli jest więcej, nie masz wyrównania do bajta.

Masz tu to samo, tylko sensowniej zapisane i z poprawionym błędem:

gg_login80 gg_login = 
{
	wxAtoi( WxEdit1->GetValue() ),
	"",
	GG_LOGIN_HASH_GG32,
	"",
	GG_STATUS_AVAIL,
	0,
	0x7,
	0,
	0,
	0,
	0,
	0,
	0x64,
	0x21,
	"",
	0
};

strcpy(gg_login.hash, (const char*) wxString::Format(wxT("%d"),hash).mb_str(wxConvUTF8));
strncpy(gg_login.language,"pl",2);
strncpy(gg_login.version, "Gadu-Gadu Client build 8.0.0.7669",0x21);

gg_header header;
header.type = GG_LOGIN80;
header.length = sizeof(gg_login);
this->connection->Write(&header, sizeof(gg_header));
this->connection->Write(&gg_login,header.length);
0

Dzięki wielkie, nie wiem co było źle w moim kodzie ale przy tym twoim jest przynajmniej odpowiedź od serwera, że nie zalogowano(ale z tym to chyba sobie poradzę)

P.S. jesli chodzi o to czy miałem wyrównaną do jednego bajta strukturę to była ,więc nie wiem dlaczego nie mogłem sie zalogować, ale teraz przynajmniej mam odpowiedź jeszcze raz dzieki :-)

0

A jednak nie nie mogę sobie poradzić założyłem nowe konto na gg(więc jestem pewien że nie mylę hasła i numeru), cały zcas otrzymuje informacje o tym że nie udało się zalogować:
(wszystko robię według http://toxygen.net/libgadu/protocol/
moje struktury:

    struct gg_header  {
        int type; /* typ pakietu */
        int length; /* długość reszty pakietu */
    }__attribute__ ((packed));

struct gg_welcome {
	int seed;	/* ziarno */
}__attribute__ ((packed));

struct gg_login80 {
        int uin;              /* numer Gadu-Gadu */
        char language[2];     /* język: "pl" */
        char hash_type;       /* rodzaj funkcji skrótu hasła */
        char hash[64];        /* skrót hasła dopełniony \0 */
        int status;           /* początkowy status połączenia */
        int flags;            /* flagi (przeznaczenie nieznane) */
        int features;         /* opcje protokołu (0x00000007)*/
        int local_ip;         /* lokalny adres połączeń bezpośrednich (nieużywany) */
        short local_port;     /* lokalny port połączeń bezpośrednich (nieużywany) */
        int external_ip;      /* zewnętrzny adres (nieużywany) */
        short external_port;  /* zewnętrzny port (nieużywany) */
        char image_size;      /* maksymalny rozmiar grafiki w KB */
        char unknown2;        /* 0x64 */
        int version_len;      /* długość ciągu z wersją (0x21) */
        char version[0x21];       /* "Gadu-Gadu Client build 8.0.0.7669" (bez \0) */
        int description_size; /* rozmiar opisu */

}__attribute__ ((packed));
struct gg_login80_ok {
	int unknown1;	/* 01 00 00 00 */
}__attribute__ ((packed));

int testFrm::gg_login_hash(unsigned char *password, unsigned int seed)
{
	unsigned int x, y, z;

	y = seed;

	for (x = 0; *password; password++) {
		x = (x & 0xffffff00) | *password;
		y ^= x;
		y += x;
		x <<= 8;
		y ^= x;
		x <<= 8;
		y -= x;
		x <<= 8;
		y ^= x;

		z = y & 0x1f;
		y = (y << z) | (y >> (32 - z));
	}

	return y;
}

moja metoda/funkcja:

 
	
	gg_welcome welcome;
    //---------------------------------------------------------------------------------------------------------
	//uzyskiwanie adresu ip
	//---------------------------------------------------------------------------------------------------------
    bool ifen = take_it->Connect("appmsg.gadu-gadu.pl");
	if( !ifen ){ wxMessageBox("nie można połaczy się z serwerem gadu-gadu"); return;}

	wxString get = "/appsvc/appmsg_ver8.asp?fmnumber=" + WxEdit1->GetValue() + "&lastmsg=0&version=8.0.0.7669"; 
	wxInputStream* Resp = take_it->GetInputStream(get);

	if(take_it->GetResponse() != 200 ) { wxMessageBox("nie można połaczy się z serwerem gadu-gadu"); return;}
	int size_buff = 1024;
    char *buff = new char[size_buff];


    Resp->Read(buff,size_buff);

    wxString factory;
    factory.append(buff);
    factory = factory.substr(3,factory.Length()+1);

    int x=factory.Find(":");
   this->ip = factory.substr(x,factory.Length()+1);
   this->ip=(this->ip).substr(6,ip.Length()+1); //uzyskane IP

   delete Resp;delete buff;
    //---------------------------------------------------------------------------------------------------------
	//łaczenie się z serwerem |||| char* ports[2]; //tablica z dwoma możliwymi portami
	//---------------------------------------------------------------------------------------------------------
  (this->Add).Hostname(this->ip);
  (this->Add).Service((this->ports)[0]);

   int r ;
  (this->connection)->SetTimeout(100);
  (this->connection)->Connect(this->Add);
   r = (this->connection)->IsConnected();
   if(!r){ wxMessageBox("Mie można się połączyc z serwerem"); return;}
            //---------------------------------------------------------------------------------------------------------
	        //pobieranie ziarna
        	//---------------------------------------------------------------------------------------------------------
             gg_header* header=new gg_header;
            (this->connection)->Read(header,sizeof(*header));
            if( header->type != GG_WELCOME ){ wxMessageBox("Mie otrzymano ziarna"); return;}else wxMessageBox("OK");
            (this->connection)->Read(&welcome,(header->length));
            delete header;
              //------------------------------------------------------------------------------------------------------                       
    //logowanie
   //------------------------------------------------------------------------------------------------------
            //1) haszowanie
            wxString temp=WxEdit2->GetValue(); //hasło
            int hash=this->gg_login_hash((unsigned char*)temp.mb_str(wxConvUTF8),welcome.seed);

    gg_login80 gg_login =
{
        wxAtoi( WxEdit1->GetValue() ), 
        "",
        GG_LOGIN_HASH_GG32,
        "",
        GG_STATUS_AVAIL,
        0,
        0x7,
        0,
        0,
        0,
        0,
        0,
        0x64,
        0x21,
        "",
        0

};
//wxINT32_SWAP_ON_BE(hash);
strcpy(gg_login.hash, (const char*)wxString::Format(wxT("%d"),hash).mb_str(wxConvUTF8));
strncpy(gg_login.language,"pl",2);
strncpy(gg_login.version, "Gadu-Gadu Client build 8.0.0.7669",0x21);

gg_header headers;
headers.type = GG_LOGIN80;
headers.length = sizeof(gg_login);
this->connection->Write(&headers, sizeof(gg_header));
this->connection->Write(&gg_login,headers.length);




            header=new gg_header;
            this->connection->Read(header,sizeof(*header));
            wxMessageBox("head : "+wxString::Format("%d",header->type));
            if(header->type == GG_LOGIN80_OK ) wxMessageBox("zalogowano");  else if(header->type ==GG_LOGIN_FAILED)wxMessageBox("Nie zalogowano");  else wxMessageBox("nie wiem");
            if(!(this->connection->IsConnected()))wxMessageBox("rozłaczono");

jaby był ktoś tak miły i rzucił na oto okiem co tu może być niezgodne z protokołem byłbym wdzięczny :-)

0

Nie widzę nic niewłaściwego. Tylko nie wiem dlaczego robisz takie rzeczy:

gg_header* header=new gg_header; //<---
(this->connection)->Read(header,sizeof(*header));
...
delete header; //<---

Gdzie tu sens?

No i czy wxConvUTF8 to świadomy wybór, czy tylko "tak o"?

0
0x666 napisał(a)

Nie widzę nic niewłaściwego. Tylko nie wiem dlaczego robisz takie rzeczy:

gg_header* header=new gg_header; //<---
(this->connection)->Read(header,sizeof(*header));
...
delete header; //<---

Gdzie tu sens?

no jak to gdzie tu sens? - za każdym razem gdy odczytuje bufor musiałbym wyzerować pola w header, więc zamiast pisać header->type=0 header->lenght=0;(przecież to nie jest moje jedyne czytanie, a jak czytam pusty bufor (bo np coś zły pakiet otrzymałem) to wtedy nie nadpisze mi zerem struktury i będę miał po raz drugi to samo w nagłówku , więc trzeba zerować)to ja tworze nowy obiekt i trzymam jego adres we wskaźniku a potem go usuwam i dla następnego wywołania read bym go znowu stworzył itp, więc imo to może wydłuża czas działania , ale ma sens.
A jeśli chodzi o UTF-8 to raczej nic nie zmienia, bo jak w kodzie zamiast tych wxEditów (które trzeba konwertować na char*) korzystam porostu z wpisania w kod hasła jako (const char*) i wtedy nic nie konwertuje z użyciem UTF-8, prócz jednej zmiany-- z hash który jest int na char*( ale to są liczby więc w ASCII i w UTF-8 mają taki sam kod), tez nie mogę się wtedy zalogować .
Naprawdę, może nie jestem niecierpliwy ale jak sie siedzi 2 dni i nie wie się co jest źle to to wpienia człowieka,za pomoc z góry dzięki :-)

0

za każdym razem gdy odczytuje bufor musiałbym wyzerować pola w header,

Heh, a kto powiedział, że nowo przydzielona pamięć jest zerowana? Zresztą twoja argumentacja jest nietrafiona, bo wystarczyłoby, żebyś zerował type przed każdym czytaniem*, raz zadeklarował header i zapewniam cię, mniej będzie pisania, a i sens większy ;-)


* w zasadzie to też jest bez sensu, bo wystarczy odczytać z socketa ilość bajtów ostatnio odczytanych i porównać z oczekiwaną liczbą.

0

Można i tak ,nie będę się o to kłócił :-) . Mnie interesuje raczej dlaczego nie mogę się zalogować i w czym tkwi ten problem??

1 użytkowników online, w tym zalogowanych: 0, gości: 1