Jump to content
Returning Members: Password Reset Required ×

[v5615] ConquerServer V3: DhExchange() - connection aborted (client sending 0 bytes)


Recommended Posts

Posted (edited)

I’ve set everything up correctly and I'm using the 5615 client from Spirited’s post.
I compiled CSV3Hook and updated csv3config.ini with the correct IPs and ports.

My GameServer is running on port 5816, and the AuthServer on 5817.
I can get past the auth server when logging in, but the connection fails when reaching the game server with the following message:

Client disconnected: Unknown (Reason: DhExchange() - connection aborted)

I tried debugging but haven’t had any success. The client is sending 0 bytes, which is causing the failure, but I can’t figure out why.

I’m also using the launcher included with the source.

Do I need to use the exact same client version as the source (5619)? I can’t even locate that version anywhere.

Edited by xFranko
Posted

This prompt is already very obvious. Try setting a breakpoint on the socket connection accept connection and debug the DHKeyExchange with the client. Only after successfully exchanging keys with the client can your socket receive the correct content

Posted

@kennylovecode I tried but I'm starting to give up, I thought it would be an issue from my client itself as to why it's sending 0 bytes? also can't tell why the exchance fails, I tried to debug but it feels like I can't get any valuable info, also tried print debugging...I feel like the issue could be with my character initilization?

 

=== CONNECTION DEBUG: GameConnect START ===
New client connected from: 26.25.24.42:56606
Socket connected: True, Alive: True
GameClient created, GameId: 1
DH Feedback object created: True
Invoking handshake handler...
=== DH EXCHANGE DEBUG: InitHandshake START ===
Client: 26.25.24.42:56606
DH DEBUG: Generated public key length: 128
DH DEBUG: Public key (first 32 bytes): 44 43 46 39 34 34 37 41 34 34 37 36 42 46 38 38 36 37 38 38 39 44 41 36 44 38 31 46 45 35 39 36
DH DEBUG: Handshake packet size: 333 bytes
DH DEBUG: Handshake packet (first 64 bytes):
  Offset 0000: 26 00 1A 27 45 1B 06 00 00 00 00 42 01 00 00 0A
  Offset 0010: 00 00 00 00 86 00 00 00 32 00 32 00 00 08 00 00
  Offset 0020: 00 00 00 00 00 00 00 00 00 08 00 00 00 00 00 00
  Offset 0030: 00 00 00 00 00 80 00 00 00 45 37 41 36 39 45 42
DH DEBUG: Sending handshake via DirectSend (unencrypted)...
DH DEBUG: DirectSend completed
=== DH EXCHANGE DEBUG: InitHandshake END ===
Handshake handler completed
Before BeginReceive - Socket connected: True, Available: 0 bytes
BeginReceive started, waiting for client reply...
=== CONNECTION DEBUG: GameConnect END ===
=== DH EXCHANGE DEBUG: DhExchange callback START ===
Client: 26.25.24.42:56606
Socket connected: True, Available: 0 bytes
DH DEBUG: EndReceive returned size: 0 bytes
DH DEBUG: ERROR - Received 0 bytes, connection aborted
DH DEBUG: Client closed connection gracefully (0 bytes)

 

Posted (edited)

Based on your log it appears the client connected, and you successfully sent back some data related to the dh exchange?

I see that the last log says client closed connection. Did it automatically disconnect after your server sent that packet? If so, then it seems likely that the client didn’t like your servers response and killed the connection. You mentioned using different source and client versions, that could possibly be it if there was any changed made to the protocol.

To rule that out spirits client page has a link to download patches. Maybe try patching your client up to the exact version of the source your using. If that doesn’t work, you will likely need to do some more debugging.

Edited by Tkblackbelt
Posted

@TkblackbeltYep the client disconnects right after the login server sends that 333 bytes packet, and I tried to find a patch from 5615 to 5619 but couldn't find any..I don't think during these 4 patches any major change happened that would cause the issue I'm having right now..so it must be something else..

Posted
18 minutes ago, xFranko said:

@TkblackbeltYep the client disconnects right after the login server sends that 333 bytes packet, and I tried to find a patch from 5615 to 5619 but couldn't find any..I don't think during these 4 patches any major change happened that would cause the issue I'm having right now..so it must be something else..

When setting up a private service for the first time, it is best to ensure that your client is the official original client. This way, you don't have to encounter DHKey exchange failures due to client issues. If you are using someone else's client, please solve the problem I mentioned first, and there is a high probability that you will be able to resolve it. For example, if you use the 5619 client, you don't necessarily need 5619. You can use any version between 5600-5930, and the difference between them won't be significant

Posted

5619 already have that md5 hash on the DH Key exchange, doesn't it? Like this

public byte[] ProcessDHSecret()
    {
        using MD5 md5 = MD5.Create();
        byte[] key = PrivateKey.ToByteArrayUnsigned();
        string sz1 = md5.ComputeHash(key, 0, key.TakeWhile(x => x != 0).Count()).ToHexString();
        string sz2 = md5.ComputeHash(Encoding.ASCII.GetBytes(string.Concat(sz1, sz1))).ToHexString();
        return Encoding.ASCII.GetBytes(string.Concat(sz1, sz2));
    }

 

Posted
26 minutes ago, Konichu said:

5619 already have that md5 hash on the DH Key exchange, doesn't it? Like this

public byte[] ProcessDHSecret()
    {
        using MD5 md5 = MD5.Create();
        byte[] key = PrivateKey.ToByteArrayUnsigned();
        string sz1 = md5.ComputeHash(key, 0, key.TakeWhile(x => x != 0).Count()).ToHexString();
        string sz2 = md5.ComputeHash(Encoding.ASCII.GetBytes(string.Concat(sz1, sz1))).ToHexString();
        return Encoding.ASCII.GetBytes(string.Concat(sz1, sz2));
    }

 

@Konichu Hmm not really looks a bit different, here's the entire DHExchange file from the GameServer

using System;
using System.Text;
using CO2_CORE_DLL.Security.Cryptography;

namespace ConquerServerV3
{
    //
    // Special thanks unknownone/Sparkie, CptSky
    //

    public class DHExchange
    {
        private const string PStr =
            "E7A69EBDF105F2A6BBDEAD7E798F76A209AD73FB466431E2E7352ED262F8C558F10BEFEA977DE9E21DCEE9B04D245F300ECCBBA03E72630556D011023F9E857F";

        private const string GStr = "05";
        public static readonly byte[] P = Encoding.ASCII.GetBytes(PStr);
        public static readonly byte[] G = Encoding.ASCII.GetBytes(GStr);

        private static string Hex(byte[] bytes)
        {
            char[] c = new char[bytes.Length * 2];
            byte b;
            for (int bx = 0, cx = 0; bx < bytes.Length; ++bx, ++cx)
            {
                b = ((byte)(bytes[bx] >> 4));
                c[cx] = (char)(b > 9 ? b + 0x37 + 0x20 : b + 0x30);
                b = ((byte)(bytes[bx] & 0x0F));
                c[++cx] = (char)(b > 9 ? b + 0x37 + 0x20 : b + 0x30);
            }

            return new string(c);
        }

        private static string PostProcessDHKey(byte[] key)
        {
            var hashService = new System.Security.Cryptography.MD5CryptoServiceProvider();
            var s1 =
                Hex(hashService.ComputeHash(key, 0,
                        key
                            .CountWhile(x => x != 0)
                    )
                );
            var s2 = Hex(hashService.ComputeHash(Encoding.ASCII.GetBytes(String.Concat(s1, s1))));
            var sresult = String.Concat(s1, s2);
            return sresult;
        }

        public static DiffieHellman New()
        {
            return new DiffieHellman(PStr, GStr);
        }

        [PacketAttribute(PacketType.HandShake)]
        private static void InitHandshake(GameClient user, Packet msg)
        {
            byte[] publicKey = Encoding.ASCII.GetBytes(user.Feedback.GenerateRequest());
            user.Send(msg.Handshake(P, G, publicKey));
        }

        [PacketAttribute(PacketType.HandshakeReply)]
        private static void CompleteHandshake(GameClient user, Packet msg)
        {
            string otherPublicKey;
            if (msg.GetHandshakeReplyKey(out otherPublicKey))
            {
                user.Feedback.HandleResponse(otherPublicKey);
                var compute = PostProcessDHKey(user.Feedback.ToBytes());
                user.Network.Language.SetKey(Encoding.ASCII.GetBytes(compute));

                user.Feedback = null; // allow resources to be freed
            }
        }
    }
}

 

Posted

I noticed that you sent the DH Key exchange request and received 0 bytes, which means that the client disconnected.

Is your Cast5 Default Seed correct?

Posted (edited)
8 hours ago, kennylovecode said:

I can almost be sure that if you can find a matching client, there won't be any problems.

@kennylovecode I got my v5615 client from Spirited's post, so it is clean, I patched it up to 5619 also from his links..and this didn't fix the issue.

Also got the database from the comments in e*pvpers, someone left it under the thread since it wasn't originally uploaded with the source.

https://www.assembla.com/spaces/conquerserverv3/documents/aL-N--KmGr4Pg0acwqEsg8/download/aL-N--KmGr4Pg0acwqEsg8

 

8 hours ago, Konichu said:

I noticed that you sent the DH Key exchange request and received 0 bytes, which means that the client disconnected.

Is your Cast5 Default Seed correct?

@Konichu From what I got from the code,

The Cast5 default seed (initialization vector/IV) is all zeros.

In ConquerServerShared\Cryptography\TQCast5.cs, the Reset() method initializes the IVs like this:

        public void Reset()
        {
            EncIvec = new byte[16];
            DecIvec = new byte[16];
            DecNum = new int[8];
            EncNum = new int[8];
        }

 

Full file:

namespace ConquerServerV3.Cryptography
{
    public unsafe class TQCast5
    {
        private byte[] EncIvec;
        private byte[] DecIvec;
        private int[] EncNum;
        private int[] DecNum;
        private TQCast5Impl Impl;

        public TQCast5()
        {
            Impl = new TQCast5Impl();
            Reset();
        }

        public void GenerateKey(byte[] kb)
        {
            var key = new byte[16];
            for (int i = 0; i < 16; i++)
                key[i] = kb[i];

            Impl.SetKey(key);
        }

        public void Reset()
        {
            EncIvec = new byte[16];
            DecIvec = new byte[16];
            DecNum = new int[8];
            EncNum = new int[8];
        }

        public void Encrypt(byte* buffer_in, int in_off, byte[] buffer_out, int out_off, int length)
        {
            byte c;
            for (int l = length, n = EncNum[0], inc = in_off, outc = 0; l > 0; l--)
            {
                if (n == 0)
                {
                    Impl.EncryptBlock(EncIvec, 0, EncIvec, 0);
                }

                c = (byte)((buffer_in[inc++] ^ EncIvec[n]) & 0xff);
                buffer_out[outc++] = c;
                EncIvec[n] = c;
                n = (n + 1) & 0x07;
                EncNum[0] = n;
            }
        }

        public void Decrypt(byte[] buffer_in, int in_off, byte* buffer_out, int out_off, int length)
        {
            byte c, cc;
            for (int l = length, n = DecNum[0], inc = in_off, outc = 0; l > 0; l--)
            {
                if (n == 0)
                {
                    Impl.EncryptBlock(DecIvec, 0, DecIvec, 0);
                }

                cc = buffer_in[inc++];
                c = DecIvec[n];
                DecIvec[n] = cc;
                buffer_out[out_off + outc] = (byte)((c ^ cc) & 0xff);
                outc++;
                n = (n + 1) & 0x07;
                DecNum[0] = n;
            }
        }
    }
}

If it matters, the default encryption key used in GameCipher.cs is: "C238xs65pjy7HU9Q" 

____________________________
Also I really just want any source that's before patch 5622 (Chi release), me and my friends just hate Chi and all that stuff that came after, we wanted to play with the Pirate and that's all and this seemed to be the only source around this patch

 

Edited by xFranko
  • xFranko changed the title to ConquerServer V3: DhExchange() - connection aborted (client sending 0 bytes)
Posted

Looking at the client I noticed it's producing some debug logs..which seems to indicate it's indeed the handshake..

ERROR: CGameSocket::ReceiveMsg() OnShakeHand failed at f:\cq2clientrelease-50.0.5\3drole\network\socket.h, 528 -- Fri Nov 28 10:54:45 2025
 

Also not sure where this path comes from 'f:\cq2clientrelease-50.0.5\3drole\' I don't have that on my PC..

Posted
3 hours ago, xFranko said:

Looking at the client I noticed it's producing some debug logs..which seems to indicate it's indeed the handshake..

ERROR: CGameSocket::ReceiveMsg() OnShakeHand failed at f:\cq2clientrelease-50.0.5\3drole\network\socket.h, 528 -- Fri Nov 28 10:54:45 2025
 

Also not sure where this path comes from 'f:\cq2clientrelease-50.0.5\3drole\' I don't have that on my PC..

It's a compile time constant that they use on logs so you know where the exception has been thrown etc. It's the path and line from the original source code. "__FILE__, __LINE__"

Your handshake request is breaking, it could be because of P on DH but it's the same as mine and TQ uses it until today.

Maybe it could be the Cast5 seed, it's the same as mine as well and I'm running 6609.

Your source is originally built for 5619? Or did you adapt anything?

Posted (edited)
47 minutes ago, Konichu said:

It's a compile time constant that they use on logs so you know where the exception has been thrown etc. It's the path and line from the original source code. "__FILE__, __LINE__"

Your handshake request is breaking, it could be because of P on DH but it's the same as mine and TQ uses it until today.

Maybe it could be the Cast5 seed, it's the same as mine as well and I'm running 6609.

Your source is originally built for 5619? Or did you adapt anything?

@Konichu 

The source is originally built for 5619 yes as per what Spirited wrote, it's the Conquer Server V3 source mentioned in this post: 

 

 

Also another memeber seems to have had such issue here: 

but well he wasn't using the Launcher provided with the source..I do use the launcher so not sure what's wrong

 

Also there was this member having similar issue with the same debug error line in their client, but he is using another source and version..

 

Idk how to approach this further tbh

Edited by xFranko
Posted
8 hours ago, xFranko said:

@Konichu 

The source is originally built for 5619 yes as per what Spirited wrote, it's the Conquer Server V3 source mentioned in this post: 

 

 

Also another memeber seems to have had such issue here: 

but well he wasn't using the Launcher provided with the source..I do use the launcher so not sure what's wrong

 

Also there was this member having similar issue with the same debug error line in their client, but he is using another source and version..

 

Idk how to approach this further tbh

Let me see your handshake packet structure

Posted
23 hours ago, xFranko said:

@Konichucould you guide me a little how to find that ? 

using System;
using System.IO;

namespace ConquerServer_v2.Client
{
    public static class DHKeyExchange
    {
        public class ServerKeyExchange
        {
            OpenSSL.DH _keyExchange;
            byte[] _serverIv;
            byte[] _clientIv;

            public byte[] CreateServerKeyPacket()
            {
                _clientIv = new byte[8];
                _serverIv = new byte[8];
                string P = "E7A69EBDF105F2A6BBDEAD7E798F76A209AD73FB466431E2E7352ED262F8C558F10BEFEA977DE9E21DCEE9B04D245F300ECCBBA03E72630556D011023F9E857F";
                string G = "05";
                _keyExchange = new OpenSSL.DH(OpenSSL.BigNumber.FromHexString(P), OpenSSL.BigNumber.FromHexString(G));
                _keyExchange.GenerateKeys();
                return GeneratePacket(_serverIv, _clientIv, P, G, _keyExchange.PublicKey.ToHexString());
            }

            public GameCryptography HandleClientKeyPacket(string PublicKey, GameCryptography cryptographer)
            {
                byte[] key = _keyExchange.ComputeKey(OpenSSL.BigNumber.FromHexString(PublicKey));
                cryptographer.SetKey(key);
                cryptographer.SetIvs(_clientIv, _serverIv);
                return cryptographer;
            }
            public byte[] GeneratePacket(byte[] ServerIV1, byte[] ServerIV2, string P, string G, string ServerPublicKey)
            {
                Random Random = new Random();
                int PAD_LEN = 11;
                int _junk_len = 12;
                string tqs = "TQServer";
                MemoryStream ms = new MemoryStream();
                byte[] pad = new byte[PAD_LEN];
                Random.NextBytes(pad);
                byte[] junk = new byte[_junk_len];
                Random.NextBytes(junk);
                int size = 47 + P.Length + G.Length + ServerPublicKey.Length + 12 + 8 + 8;
                BinaryWriter bw = new BinaryWriter(ms);
                bw.Write(pad);
                bw.Write(size - PAD_LEN);
                bw.Write((UInt32)_junk_len);
                bw.Write(junk);
                bw.Write((UInt32)ServerIV2.Length);
                bw.Write(ServerIV2);
                bw.Write((UInt32)ServerIV1.Length);
                bw.Write(ServerIV1);
                bw.Write((UInt32)P.ToCharArray().Length);
                foreach (char fP in P.ToCharArray())
                {
                    bw.BaseStream.WriteByte((byte)fP);
                }
                bw.Write((UInt32)G.ToCharArray().Length);
                foreach (char fG in G.ToCharArray())
                {
                    bw.BaseStream.WriteByte((byte)fG);
                }
                bw.Write((UInt32)ServerPublicKey.ToCharArray().Length);
                foreach (char SPK in ServerPublicKey.ToCharArray())
                {
                    bw.BaseStream.WriteByte((byte)SPK);
                }
                foreach (char tq in tqs.ToCharArray())
                {
                    bw.BaseStream.WriteByte((byte)tq);
                }
                byte[] Packet = new byte[ms.Length];
                Packet = ms.ToArray();
                ms.Close();
                return Packet;
            }
        }
    }
}



you are using this code , right? 

Posted

@kennylovecode Hmm, the entire DHExchange file I shared it in previous reply here 

Also your code mentions v2 I am using v3

 

Quote

May I ask if GameServer crashes when you disconnect from the client?

Nope it doesn't crash..only the client disconnects...the client entirely crashes in case I set the IPs to 127.0.0.1 (which is expected I believe)

 

Posted
1 hour ago, xFranko said:

@kennylovecode Hmm, the entire DHExchange file I shared it in previous reply here 

Also your code mentions v2 I am using v3

 

Nope it doesn't crash..only the client disconnects...the client entirely crashes in case I set the IPs to 127.0.0.1 (which is expected I believe)

 

where the v3 download from, i try to slove the problem

Posted (edited)
7 minutes ago, kennylovecode said:

where the v3 download from, i try to slove the problem

@kennylovecode Thank you! It's from Spirited's post here https://mega.nz/file/4RYh1QqB#wFWD65PgEatq05GD2pjld_7w-D7fO8t1wHznkqhvNNQ

Also got the database from the comments in e*pvpers, someone left it under the thread since it wasn't originally uploaded with the source.

https://www.assembla.com/spaces/conquerserverv3/documents/aL-N--KmGr4Pg0acwqEsg8/download/aL-N--KmGr4Pg0acwqEsg8

 

 

Edited by xFranko
  • xFranko changed the title to [v5615] ConquerServer V3: DhExchange() - connection aborted (client sending 0 bytes)

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...