From 6c417a45f25de9480ef200177c7bed0f4782eb19 Mon Sep 17 00:00:00 2001 From: sje Date: Thu, 28 Jun 2007 08:34:59 +0000 Subject: git-svn-id: https://server.scottellis.com.au/svn/mim_plugs@219 4f64403b-2f21-0410-a795-97e2b3489a10 --- MySpace/server_con.cpp | 129 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 112 insertions(+), 17 deletions(-) (limited to 'MySpace/server_con.cpp') diff --git a/MySpace/server_con.cpp b/MySpace/server_con.cpp index f3c6d79..79f20b8 100644 --- a/MySpace/server_con.cpp +++ b/MySpace/server_con.cpp @@ -1,14 +1,32 @@ #include "common.h" #include "server_con.h" #include "net.h" +#include "arc4.h" +#include "options.h" #include "NetMessage.h" #define SERVER_READ_BUFFER_SIZE (1024 * 32) +/* TODO: obtain IPs of network interfaces from user's machine, instead of + * hardcoding these values below (used in msim_compute_login_response). + * This is not immediately + * important because you can still connect and perform basic + * functions of the protocol. There is also a high chance that the addreses + * are RFC1918 private, so the servers couldn't do anything with them + * anyways except make note of that fact. Probably important for any + * kind of direct connection, or file transfer functionality. + */ + +#define LOGIN_IP_LIST "\x00\x00\x00\x00\x05\x7f\x00\x00\x01\x00\x00\x00\x00\x0a\x00\x00\x40\xc0\xa8\x58\x01\xc0\xa8\x3c\x01" +#define LOGIN_IP_LIST_LEN 25 + +#define NONCE_SIZE 0x20 + int status = ID_STATUS_OFFLINE; bool server_running = false, server_stop = false; HANDLE server_connection = 0; +int sesskey; void CALLBACK sttMainThreadStatusCallback( ULONG dwParam ) { if(status != dwParam) { @@ -19,12 +37,75 @@ void CALLBACK sttMainThreadStatusCallback( ULONG dwParam ) { } int waitcallback(unsigned int *timeout) { - PUShowMessage("waitcallback", SM_NOTIFY); + //PUShowMessage("waitcallback", SM_NOTIFY); return server_stop ? 0 : 1; } int try_ports[9] = {1863, 6660,6661,6662,6665,6668,6669,80,0443}; +void try_login(NetMessage &msg, HANDLE connection) { + char nonce[NONCE_SIZE * 2 + 2], *nc1 = nonce, *nc2 = nonce + NONCE_SIZE; + int size = NONCE_SIZE * 2 + 2; + if(msg.get_data("nc", nonce, &size) && size == NONCE_SIZE * 2) { + SHA1_INTERFACE sha1; + mir_sha1_ctx sha1_ctx; + mir_getSHA1I(&sha1); + + ARC4_INTERFACE arc4; + mir_arc4_ctx arc4_ctx; + mir_getARC4I(&arc4); + + char *ch_resp; + mir_sha1_byte_t pw_hash[20]; + int ch_resp_size; + wchar_t wpw[256]; + mir_sha1_byte_t key[20]; + char email[256]; + +#ifdef _UNICODE + _tcscpy(wpw, options.pw); + WideCharToMultiByte(CP_UTF8, 0, options.email, -1, email, 256, 0, 0); +#else + strcpy(email, options.email); + MultiByteToWideChar(code_page, 0, options.pw, -1, wpw, 256); +#endif + + sha1.sha1_hash((mir_sha1_byte_t*)wpw, wcslen(wpw) * sizeof(wchar_t), pw_hash); + + sha1.sha1_init(&sha1_ctx); + sha1.sha1_append(&sha1_ctx, (mir_sha1_byte_t*)pw_hash, 20); + sha1.sha1_append(&sha1_ctx, (mir_sha1_byte_t*)nc2, NONCE_SIZE); + sha1.sha1_finish(&sha1_ctx, key); + + arc4.arc4_init(&arc4_ctx, (char *)key, 0x10); + + ch_resp_size = NONCE_SIZE + strlen(email) + LOGIN_IP_LIST_LEN; + ch_resp = new char[ch_resp_size]; + memcpy(ch_resp, nc1, NONCE_SIZE); + memcpy(ch_resp + NONCE_SIZE, email, strlen(email)); + memcpy(ch_resp + NONCE_SIZE + strlen(email), LOGIN_IP_LIST, LOGIN_IP_LIST_LEN); + + arc4.arc4_crypt(&arc4_ctx, ch_resp, ch_resp, ch_resp_size); + + ClientNetMessage reply; + reply.add_int("login2", 196610); + reply.add_string("username", email); + reply.add_data("response", ch_resp, ch_resp_size); + reply.add_int("clientver", 673); + reply.add_int("reconn", 0); + reply.add_int("status", 100); + reply.add_int("id", 1); + + delete[] ch_resp; + + char packet[4096]; + int packet_size = reply.make_packet(packet, 4096); + Netlib_Send(server_connection, packet, packet_size, MSG_DUMPASTEXT); + } else { + PUShowMessage("Nonce format error", SM_NOTIFY); + } +} + void __cdecl ServerThreadFunc(void*) { NETLIBOPENCONNECTION conn_data = {0}; conn_data.cbSize = sizeof(NETLIBOPENCONNECTION); @@ -34,7 +115,8 @@ void __cdecl ServerThreadFunc(void*) { conn_data.timeout = 10; conn_data.waitcallback = waitcallback; - QueueUserAPC(sttMainThreadStatusCallback, mainThread, ID_STATUS_CONNECTING); + int conn_stat = ID_STATUS_CONNECTING; + QueueUserAPC(sttMainThreadStatusCallback, mainThread, conn_stat); server_running = true; @@ -44,12 +126,15 @@ void __cdecl ServerThreadFunc(void*) { int tries = 0; bool login = true; + HANDLE connection = 0; + while(!Miranda_Terminated() && !server_stop) { if(login) { - if(server_connection) Netlib_CloseHandle(server_connection); - server_connection = (HANDLE)CallService(MS_NETLIB_OPENCONNECTION, (WPARAM)hNetlibUser, (LPARAM)&conn_data); + if(connection) Netlib_CloseHandle(connection); + QueueUserAPC(sttMainThreadStatusCallback, mainThread, conn_stat++); + connection = (HANDLE)CallService(MS_NETLIB_OPENCONNECTION, (WPARAM)hNetlibUser, (LPARAM)&conn_data); } - bytes = Netlib_Recv(server_connection, (char *)recv_buffer, SERVER_READ_BUFFER_SIZE, MSG_DUMPASTEXT); + bytes = Netlib_Recv(connection, (char *)recv_buffer, SERVER_READ_BUFFER_SIZE, MSG_DUMPASTEXT); if(bytes == 0) { PUShowMessage("Connection closed", SM_NOTIFY); @@ -59,32 +144,42 @@ void __cdecl ServerThreadFunc(void*) { break; } else if(bytes == SOCKET_ERROR) { PUShowMessage("Socket ERROR", SM_NOTIFY); - break; + if(login && tries < 9) { + conn_data.wPort = try_ports[tries++]; + } else + break; } else { if(login) { + QueueUserAPC(sttMainThreadStatusCallback, mainThread, conn_stat++); login = false; - QueueUserAPC(sttMainThreadStatusCallback, mainThread, ID_STATUS_ONLINE); + server_connection = connection; + DBWriteContactSettingDword(0, MODULE, "LastPort", conn_data.wPort); } - mir_snprintf(mt, 256, "recvd %d bytes", bytes); - PUShowMessage(mt, SM_NOTIFY); + //mir_snprintf(mt, 256, "recvd %d bytes", bytes); + //PUShowMessage(mt, SM_NOTIFY); NetMessage msg; msg.parse(recv_buffer, bytes); - if(msg.exists(NMString("lc"))) { - NMString val; - msg.get(NMString("lc"), val); - mir_snprintf(mt, 256, "Login message: type is %s", val.text); - PUShowMessage(mt, SM_NOTIFY); - // challenge/response: - // + if(msg.exists(NMString("error"))) { + char errmsg[256]; + if(msg.get_string("errmsg", errmsg, 256)) + PUShowMessage(errmsg, SM_WARNING); + } else if(msg.get_int("lc") == 1) { + QueueUserAPC(sttMainThreadStatusCallback, mainThread, conn_stat++); + try_login(msg, server_connection); + } else if(msg.get_int("lc") == 2) { + sesskey = msg.get_int("sesskey"); + QueueUserAPC(sttMainThreadStatusCallback, mainThread, ID_STATUS_ONLINE); } else if(msg.exists(NMString("persistr"))) { + /* NMString cmd, dsn, lid; msg.get(NMString("cmd"), cmd); msg.get(NMString("dsn"), dsn); msg.get(NMString("lid"), lid); - mir_snprintf(mt, 256, "Perist message: type is %s,%s,%s", cmd.text, dsn.text, lid.text); + mir_snprintf(mt, 256, "Peristr message: type is %s,%s,%s", cmd.text, dsn.text, lid.text); PUShowMessage(mt, SM_NOTIFY); + */ } } } -- cgit v1.2.3