seit Tagen beiße ich mir die Zähne aus. Ich habe ein altes Delphi-Programm, das einen sog. Extentended Communication Header verwendet. Dieses Teil sendet einen Byte-Strom-Kopf über den Socket, bevor die eigentlichen Daten im Klartext versendet werden wie Benutzername, Passwort ...
Ich habe mir im Augenblick so beholfen, dass ich mit einem Netzwerksniffer ein Char-Byte-Array kopiert habe und 1:1 übergebe. Das ist natürlich superbillig und es funktioniert nicht richtig, weil ich keine korrekte zur jeweiligen SessionID passenden ClientID übergeben kann ...
Ich wäre super-dankbar, wenn jemand eine Idee hat. Wie wäre es mit arraycopy in C++ nachbilden?
So sieht der Delphi-Part aus:
var
ech : TExtendedCommunicationHeader;
...
ZeroMemory(@ech, SizeOf(ech));
ech.PacketType := gcTCPptRequestLogin;
ech.ClientID := SimpleHash(SID);
ech.DataSize := 0;
FTCPClient.WriteBuffer(ech, SizeOf(ech), True);
So sieht bisher mein C++ Part aus:
typedef struct {
unsigned char type[16];
int len;
} ExtendedCommunicationHeader;
unsigned char gcTCPptRequestLogin[16] = { 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xc4, 0x0c, 0x86 };
#define ECH_TYPE_SIZE 16
#define ECH_LEN_SIZE 4
#define ECH_SIZE 20
bool login(std::string user, std::string pwd) {
ExtendedCommunicationHeader ech;
memcpy(ech.gcTCPptRequestLogin,ECH_TYPE_SIZE);
char loginbuffer[128];
sprintf(loginbuffer,"UserName=%s\r\nPassword=%s\r\ nNotScrambled=1\r\nSupportsUDP=False\r\n", user.c_str(), pwd.c_str());
if(!pwd.empty()) {
//login data
//sprintf(loginbuffer,"Password=%s\r\n", pwd.c_str());
printf(loginbuffer,"Password=%s\r\n", pwd.c_str());
}
// generate session uiid
sprintf(loginbuffer,"%sSID={%s}\r\n", loginbuffer, this->sessionid);
ech.len=strlen(loginbuffer);
// connect the server
if(connectToServer()) {
printf("send header\n");
int sent = send(this->s,&ech, ECH_SIZE,0);
printf("send login info\n");
sent += send(this->s,loginbuffer, ech.len,0);
printf("receive answer\n");
int cnt = recv(this->s,&ech,ECH_SIZE,0);
if(memcmp(gcTCPptAnswerLoginRequestOK,ech.type,1)= =0) {
printf("login ok\n");
return true;
} else {
printf("login something wrong ...\n");
printHex(&ech,ECH_TYPE_SIZE);
}
}
return false;
}
In Java habe ich es hinbekommen, da kenne ich mich besser aus als in C++, so sieht es in Java funktionierend aus:
try {
socket = (SocketConnection)Connector.open("socket://" + host + ":" + port, 3, true);
int status = -1;
dos = socket.openDataOutputStream();
dis = socket.openDataInputStream();
buff = new byte[20];
all_receive_byte = all_receive_byte + 20;
System.arraycopy(conn_type.toByte(gcTCPptRequestLo gin, true), 0, buff, 0, 4);
System.arraycopy(conn_type.toByte(t_data_time, true), 0, buff, 4, 8);
System.arraycopy(conn_type.toByte(reserved, true), 0, buff, 12, 4);
System.arraycopy(conn_type.toByte(auth.length(), true), 0, buff, 16, 4);
dos.write(buff, 0, 20);
buff = new byte[auth.length()];
buff = auth.getBytes();
all_receive_byte = all_receive_byte + auth.length();
dos.write(buff, 0, auth.length());
buff = new byte[20];
dis.read(buff);
all_receive_byte = all_receive_byte + 20;
status = conn_type.toInt(buff, true);
// edited 14.03.2010 SGI
if(status != gcTCPptAnswerLoginRequestOK) {
is_authorize = false;
return 2;
} else {
is_authorize = true;
return 1;
}