Protokół GG. Problem z zalogowaniem się.

0

Znowu ja :)
Spotkał się ktoś (a właściwie: spotkałeś się) z taką sytuacją, że kiedy odbierasz gg_notify_reply80 12 bajtów przed zerem to krzaki?
Czyli np. opis infobota wygląda tak:

                [0]	78 'N'	char
		[1]	111 'o'	char
		[2]	119 'w'	char
		[3]	97 'a'	char
		[4]	32 ' '	char
		[5]	102 'f'	char
		[6]	117 'u'	char
		[7]	110 'n'	char
		[8]	107 'k'	char
		[9]	99 'c'	char
		[10]	106 'j'	char
		[11]	97 'a'	char
		[12]	58 ':'	char
		[13]	32 ' '	char
		[14]	115 's'	char
		[15]	101 'e'	char
		[16]	110 'n'	char
		[17]	110 'n'	char
		[18]	105 'i'	char
		[19]	107 'k'	char
		[20]	32 ' '	char
		[21]	124 '|'	char
		[22]	32 ' '	char
		[23]	119 'w'	char
		[24]	119 'w'	char
		[25]	119 'w'	char
		[26]	46 '.'	char
		[27]	105 'i'	char
		[28]	110 'n'	char
		[29]	102 'f'	char
		[30]	111 'o'	char
		[31]	98 'b'	char
		[32]	111 'o'	char
		[33]	116 't'	char
		[34]	46 '.'	char
		[35]	112 'p'	char
		[36]	108 'l'	char
		[37]	47 '/'	char
		[38]	115 's'	char
		[39]	101 'e'	char
		[40]	110 'n'	char
		[41]	110 'n'	char
		[42]	105 'i'	char
		[43]	107 'k'	char
		[44]	-3 'ý'	char // tu się krzaki zaczynają
		[45]	-3 'ý'	char
		[46]	-3 'ý'	char
		[47]	-3 'ý'	char
		[48]	-85 '«'	char
		[49]	-85 '«'	char
		[50]	-85 '«'	char
		[51]	-85 '«'	char
		[52]	-85 '«'	char
		[53]	-85 '«'	char
		[54]	-85 '«'	char
		[55]	-85 '«'	char
		[56]	0	char // a dopiero tutaj jest 0

I niestety to 12 to nie jest stała liczba, tych krzaków jest różnie w zależności od długości opisu.
Jakiś pomysł jak się ich pozbyć?

0

Przecież w opisie masz napisane, że description nie kończy się zerem. Długość opisu zapisaną masz w description_size.

0

I to tak właśnie wygląda, że z tej struktury wyciąłem description, tworzę dynamicznie tablicę charów o wielkości description_size i do tej tablicy odbieram opis.

0

To zrób tablicę o jeden znak większą i ustaw:

desc[reply.description_size] = 0;
0

No i gra gitara, dzięki.

0

A czy ktoś może rozwiązał problem polskich znaków przy wysyłaniu wiadomości?
Kiedy używam wstringa

wstring html_text = L"<span style=\"color:\#000000; font-family:'MS Shell Dlg 2'; font-size:9pt; \">"; html_text += L"ąść"; html_text += L"</span>";

Wiadomość nie dochodzi.

Kiedy tak samo użyje zwykłego stringa- wiadomość dochodzi z krzakami zamiast polskich znaków.

0

A gdzie w opisie protokołu masz napisanie, że wiadomość masz wysyłać w utf-16? Wiadomość powinna być w utf-8.

0

Czyli WideCharToMultiByte?

0

Jeśli dobrze pamiętam, to tak.

0

Jednak coś jest nie tak.

        char buf[] = { "Sięmanko" };
	int ile = MultiByteToWideChar(CP_UTF8, 0, buf, strlen(buf), NULL, 0);
	wchar_t *wide = new wchar_t[ile];
	if(MultiByteToWideChar(CP_UTF8, 0, buf, strlen(buf), wide, ile) == 0)
	{
		return false;
	}

        wstring html_text;
	html_text.assign(content, wcslen(content));

        // tutaj wysyłanie, które działa 

Z takiego kodu nie wszystkie znaki dochodzą, oczywiście polskie nie dochodzą, a na końcu zawsze dwa znaki zapytania.

0

Przecież pisałem, że masz wysłać tekst w kodowaniu utf-8, a nie utf-16! Wcześniej pytałeś o WideCharToMultiByte, a w kodzie widzę MultiByteToWideChar. Skup się!

Jeszcze raz dla jasności napiszę: funkcją WideCharToMultiByte konwertujesz tekst w kodowaniu utf-16 (wchar_t[]/wstring) do utf-8 (char[]). W przypadku tekstu ansi cała konwersja musi być dwustopniowa:

ANSI -- MultiByteToWideChar --> UTF-16 -- WideCharToMultiByte --> UTF-8

Mam nadzieję, że teraz wszystko jasne.

0

mógłby ktoś podać jak powinien wyglądać hash dla jakiegoś przykładowego hasła i seeda?

z góry dzieki

0

eee, normalnie?
Ściągnij sobie bibliotekę OpenSSL i sobie tą bibliotekę wygeneruj.
Masz przykład w opisie protokołu.

0

bo nie chce używac OpenSSL, nie bede instalował całej biblioteki dla jednej funkcji skrótu. pozaty, program będzie potem przeniesiony na inną platformę.

0
ahv napisał(a)

bo nie chce używac OpenSSL, nie bede instalował całej biblioteki dla jednej funkcji skrótu. pozaty, program będzie potem przeniesiony na inną platformę.

http://www.dominik-reichl.de/articles/csha1/csha1.shtml

google :)

0

nie rozumiemy się, mam zaimplementowane SHA1, chce porównać wyniki dla jakiś konkretnych danych, bo niestety mój program nie chce się zalogować i szukam przyczyny.

dla:
hasło: abcdef
seed: 1691378518

mam:
-127 89 123 -62 113 -37 -111 101 74 -75 124 40 -46 -79 36 6 -49 44 -102 -72 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0
#pragma comment(lib,"libeay32") // \Program Files\Gadu-Gadu\libeay32.dll
#include <stdio.h>

typedef struct SHAstate_st {
	int h0,h1,h2,h3,h4;
	int Nl,Nh;
	int data[16];
	int num;
} SHA_CTX;
int __declspec(dllimport) __cdecl SHA_Init(SHA_CTX*);
int __declspec(dllimport) __cdecl SHA_Update(SHA_CTX*,void*,int);
int __declspec(dllimport) __cdecl SHA_Final(void*, SHA_CTX*);

void gg_sha_hash(char *password, unsigned int seed, unsigned char *result)
{
	SHA_CTX ctx;

	SHA_Init(&ctx);
	SHA_Update(&ctx, password, strlen(password));
	SHA_Update(&ctx, &seed, sizeof(seed));
	SHA_Final(result, &ctx);
}

int main()
{
	unsigned char sha[20];
	int a;

	gg_sha_hash("abcdef", 1691378518, sha);
	for (a=0; a<19; a++)
	{
		printf("%u,", sha[a]);
	}
	return 0&printf("%u\n", sha[19]);
}

Wypluwa28,52,4,248,159,213,63,43,88,197,195,189,184,178,80,68,246,157,140,192

0

Na poprawnie zalogowanym kliencie próbuje zmienić status. Dostaje w odpowiedzi 4, więc powinien byc dostepny z opisem ale na oryginalnym kliencie nie następuje żadna zmiana :/ ....oto kod:

gg_new_status80 status;
		header header;
		header.type=GG_NEW_STATUS80;
		header.length=sizeof(status);
		send(sock, (char*)&header, sizeof(header),0);

		status.status = 0x0004; // dostepny z opisem
		status.flags = 0x00000001;
		sprintf(status.description, "opis");
		status.description_size = strlen(status.description);
  
        if(send(sock, (char*)&status, sizeof(status), 0))
        {
                
                printf("Wyslano status\n");
        }
        
  int buf2 = 0;
        recv(sock, (char*)&buf2, 4, 0);
        cout << buf2;
0

<quote=sapero><cpp>#pragma comment(lib,"libeay32") // \Program Files\Gadu-Gadu\libeay32.dll
#include <stdio.h>

void gg_sha_hash(char *password, unsigned int seed, unsigned char *result)
{
SHA_CTX ctx;

SHA_Init(&ctx);
SHA_Update(&ctx, password, strlen(password));
SHA_Update(&ctx, &seed, sizeof(seed));
SHA_Final(result, &ctx);

}

Co robi dokladnie funkcja SHA_Update i dlaczego jest wywoływana 2 razy ?

0

Dodaje kolejne dane na podstawie których jest wyliczany hasz SHA.

0
byku_guzio napisał(a)

Dodaje kolejne dane na podstawie których jest wyliczany hasz SHA.

Tak obrazowo, dwukrotne wywołanie:

SHA_Update("abcdef");
SHA_Update("12345";

jest równoznaczne z jednokrotnym

SHA_Update("abcdef12345"); ?

Jezeli nie jest rownoznaczne to co zrobic aby było (równoznaczne z jednokrotnym)?

0

Powinno być równoznaczne - możesz to sprawdzić czy wygeneruje taki sam hasz przy dwóch wywołaniach i czy przy jednym.

0

nie mam mozliwosci sprawdzenia na chwile obecna, dlatego pytam - liczylem ze bedzie szybciej

0

dotarłem do takich źródeł - myśle ze analiza tego moze dac odpowiedz co tak naprawde robi funkcja sha1_update:

int HASH_UPDATE (HASH_CTX *c, const void *data_, size_t len)
{
const unsigned char *data=data_;
unsigned char *p;
HASH_LONG l;
size_t n;

if (len==0) return 1;

l=(c->Nl+(((HASH_LONG)len)<<3))&0xffffffffUL;
/* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
 * Wei Dai <[email protected]> for pointing it out. */
if (l < c->Nl) /* overflow */
	c->Nh++;
c->Nh+=(len>>29);	/* might cause compiler warning on 16-bit */
c->Nl=l;

n = c->num;
if (n != 0)
	{
	p=(unsigned char *)c->data;

	if ((n+len) >= HASH_CBLOCK)
		{
		memcpy (p+n,data,HASH_CBLOCK-n);
		HASH_BLOCK_DATA_ORDER (c,p,1);
		n      = HASH_CBLOCK-n;
		data  += n;
		len   -= n;
		c->num = 0;
		memset (p,0,HASH_CBLOCK);	/* keep it zeroed */
		}
	else
		{
		memcpy (p+n,data,len);
		c->num += (unsigned int)len;
		return 1;
		}
	}

n = len/HASH_CBLOCK;
if (n > 0)
	{
	HASH_BLOCK_DATA_ORDER (c,data,n);
	n    *= HASH_CBLOCK;
	data += n;
	len  -= n;
	}

if (len != 0)
	{
	p = (unsigned char *)c->data;
	c->num = len;
	memcpy (p,data,len);
	}
return 1;
}
0

EXAMPLES
% sha1::sha1 "Tcl does SHA1"
285a6a91c45a9066bf39fcf24425796ef0b2a8bf

   % sha1::hmac Sekret "Tcl does SHA1"
   ae6251fa51b95b18cba2be95eb031d07475ff03c


   % set tok [sha1::SHA1Init]
   ::sha1::1
   % sha1::SHA1Update $tok "Tcl "
   % sha1::SHA1Update $tok "does "
   % sha1::SHA1Update $tok "SHA1"
   % sha1::Hex [sha1::SHA1Final $tok]
   285a6a91c45a9066bf39fcf24425796ef0b2a8bf

źródło: http://developer.apple.com/library/mac/#DOCUMENTATION/Darwin/Reference/ManPages/mann/sha1.n.html

0

Czy ktoś wie jak zamienic wywołanie

np.

SHA_Update(&ctx, password, strlen(password));
SHA_Update(&ctx, &seed, sizeof(seed));

na jedno SHA_Update(&ctx.....)

0

Po co?
Zacznij używać OpenSSL to żadnych problemów z hashem nie będziesz miał.

0
kiedyspamietalem napisał(a)

Po co?
Zacznij używać OpenSSL to żadnych problemów z hashem nie będziesz miał.

A po to, że na platformie .NET nie ma funkcji sha1_update jest po prostu jedna funkcja ktora przyjmuje byte[] i zwraca hash w tablicy byte[]

0

Trochę odkopuje ale dla potomnych może się przydać. Dla .NET w c# wyliczenie hasha sha1 dla gg wygląda następująco

        private byte[] getSHA1Hash(string password, uint seed)
        {
            byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
            byte[] seedBytes = BitConverter.GetBytes(seed);
            byte[] bytes = new byte[passwordBytes.Length + seedBytes.Length];
            passwordBytes.CopyTo(bytes, 0);
            seedBytes.CopyTo(bytes, passwordBytes.Length);
            SHA1 sha1Hash = SHA1Managed.Create();
            return sha1Hash.ComputeHash(bytes);
        } 

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