diff options
author | sje <sje@4f64403b-2f21-0410-a795-97e2b3489a10> | 2007-06-28 08:34:59 +0000 |
---|---|---|
committer | sje <sje@4f64403b-2f21-0410-a795-97e2b3489a10> | 2007-06-28 08:34:59 +0000 |
commit | 6c417a45f25de9480ef200177c7bed0f4782eb19 (patch) | |
tree | f49a12a076e5fa20a95430998816a92fb741ebee /MySpace/server_con.cpp | |
parent | 81a69c4c216350d48d962ac43fea3108498bbf33 (diff) |
git-svn-id: https://server.scottellis.com.au/svn/mim_plugs@219 4f64403b-2f21-0410-a795-97e2b3489a10
Diffstat (limited to 'MySpace/server_con.cpp')
-rw-r--r-- | MySpace/server_con.cpp | 129 |
1 files changed, 112 insertions, 17 deletions
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);
+ */
}
}
}
|