• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 311, comments - 0, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理
            mangosd是MaNGOS-Zero項目中的游戲邏輯進程,玩家一旦與realmd的keyexchange過程完成后(詳細內容見《realmd認證登錄服務器(一):認證登錄基本流程》),便只與mangosd進行交互。而客戶端與realmd的連接也會在客戶端向mangosd發(fā)送enterworld之后斷開。

            本文將介紹客戶端連接到mangosd后,mangosd認證客戶端合法性并最終建立RC4流加密的過程。具體過程如下:

             

            (1) 客戶端與mangosd建立TCP連接后,mangosd會向客戶端發(fā)送消息SMSG_AUTH_CHALLENGE

               1: int WorldSocket::open (void *a)
               2: {
               3:     ........
               4:  
               5:     // Send startup packet.
               6:     WorldPacket packet (SMSG_AUTH_CHALLENGE, 4);
               7:     packet << m_Seed;
               8:     if (SendPacket (packet) == -1)
               9:         return -1;
              10:  
              11:     ........
              12: }

            m_Seed是一個隨機數,每次客戶端連接上來的時生成一個新的隨機數(隨著WorldSocket的創(chuàng)建而初始化)。

             

            (2)客戶端收到SMSG_AUTH_CHALLENGE消息后,知道服務器要求其提供身份認證信息,于是開始構造CMSG_AUTH_SESSION消息。(以下代碼并非客戶端真實代碼)

               1: //client do auth
               2: {
               3:     BigNumber clientSeed;
               4:     clientSeed.SetRand(4 * 8);
               5:     sha.Initialize();
               6:     sha.UpdateData("abu");
               7:     uint32 t = 0;
               8:     sha.UpdateData((uint8 *)&t, 4);
               9:     sha.UpdateBigNumbers(&clientSend, NULL);
              10:     sha.UpdateData((uint8 *)&serverSeed, 4);
              11:     sha.UpdateBigNumbers(&K, NULL);
              12:     sha.Finalize();
              13:  
              14:     uint32 unk2;
              15:     ByteBuffer pktbuf;
              16:     string account = "abu";
              17:     uint16 pktbuf_size = 4+4+4+account.length()+4+20;
              18:     EndianConvertReverse(pktbuf_size);
              19:     pktbuf << uint16(pktbuf_size);
              20:     pktbuf << uint32(CMSG_AUTH_SESSION);
              21:     pktbuf << uint32(5875); //build version
              22:     pktbuf << unk2;
              23:     pktbuf << account;
              24:     pktbuf.append(clientSeed.AsByteArray(4), 4);
              25:     pktbuf.append(sha.GetDigest(), 20);
              26:  
              27:     send((char const*)pktbuf.contents(), pktbuf.size());
              28: }

            其中最為關鍵的是構造20位的sha驗證密文M:

            M = sha(t, account, clientSeed, serverSeed, K);

            t為0;account是明文的用戶名;clientSeed是由客戶端生成的隨機數,用于本次連接游戲session;serverSeed是SMSG_AUTH_CHALLENGE消息發(fā)過來的服務器隨機數;K是之前和realmd交互做keyexchange時生成的,由服務器和客戶端分別進行計算,SRP6算法要求(保證)兩邊的計算結果一致,服務器端保存在realmd.account.sessionkey字段。

             

             

             

             

            (3)服務器收到客戶端發(fā)來的CMSG_AUTH_SESSION,首先對收到的數據包進行分析,客戶端發(fā)來的數據包的包頭如下:

               1: struct ClientPktHeader
               2: {
               3:     uint16 size; //packet_size except itself
               4:     uint32 cmd;  //opCode
               5: };

            收到客戶端發(fā)來的data,處理流程可以簡化為如下代碼:

            int WorldSocket::handle_input (ACE_HANDLE)

            {

            ……………

            handle_input_missing_data()

            {

            handle_input_header();

            handle_input_payload()

            {

            const int ret = ProcessIncoming (m_RecvWPct);

            }

            }

            }

            在ProcessIncoming()函數中使用switch case把客戶端發(fā)過來的不同的opcode定位到不同的處理函數中,而登錄認證過程需要定位到int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)函數。

            在HandleAuthSession()函數中,服務器以客戶端相同的方式計算sha密文,并和客戶端傳來的做比較,如果相同則認證通過,然后創(chuàng)建WorldSession實例,初始化m_Crypt成員,以便以后服務器和客戶端之間交互的RC4對稱加密使用。最后把新創(chuàng)建的WorldSession對象的m_Session添加到游戲世界中,添加完畢后,在游戲世界的主線程(Update線程)可以對該客戶端做相應的處理。

             

            (4)HandleAuthSession()處理的最后會使用下面的代碼,進行判斷:如果session可以作為normal_session的而不是queue_session則發(fā)送SMSG_AUTH_RESPONSE消息,至此所有發(fā)送的消息都將進行RC4的流加密。

               1: void World::AddSession_ (WorldSession* s)
               2: {
               3:     ........
               4:  
               5:     if (pLimit > 0 && Sessions >= pLimit && s->GetSecurity () == SEC_PLAYER )
               6:     {
               7:         AddQueuedSession(s);
               8:         UpdateMaxSessionCounters();
               9:         DETAIL_LOG("PlayerQueue: Account id %u is in Queue Position (%u).", s->GetAccountId (), ++QueueSize);
              10:         return;
              11:     }
              12:  
              13:     // Checked for 1.12.2
              14:     WorldPacket packet(SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4);
              15:     packet << uint8 (AUTH_OK);
              16:     packet << uint32 (0);                                   // BillingTimeRemaining
              17:     packet << uint8 (0);                                    // BillingPlanFlags
              18:     packet << uint32 (0);                                   // BillingTimeRested
              19:     s->SendPacket (&packet);
              20:  
              21:     ........
              22: }

             

            總結:

             

             

            (1)realmd和mangosd在登錄認證過程中,相互之間基本不通信,通過MySQL來傳遞client認證所需的sessionkey。

            (2)每次客戶端和mangosd之間認證時,各自生成一個隨機數Seed,保證在傳輸過程中隱藏sessionkey。

            久久久久成人精品无码 | 久久99精品久久久久久动态图 | 日韩欧美亚洲综合久久影院Ds| 国产精品va久久久久久久| 久久亚洲高清综合| 久久婷婷五月综合国产尤物app| 99久久精品免费| 久久亚洲精品无码aⅴ大香| 久久九九亚洲精品| 国产亚洲精久久久久久无码77777| 国内精品久久久久影院免费| 日韩欧美亚洲综合久久影院Ds| 国内精品九九久久久精品| 天天综合久久一二三区| 久久美女人爽女人爽| 色综合久久久久无码专区| 婷婷久久综合九色综合九七| 久久精品一区二区| 久久精品无码午夜福利理论片| 天天做夜夜做久久做狠狠| 狠狠人妻久久久久久综合| 久久精品9988| 久久精品亚洲一区二区三区浴池| 中文字幕亚洲综合久久菠萝蜜 | 人人妻久久人人澡人人爽人人精品| 99久久精品免费看国产| 精品一区二区久久| 久久99精品国产麻豆| 久久无码人妻一区二区三区| 久久久久av无码免费网| 无码任你躁久久久久久| 亚洲午夜久久久| 亚洲综合熟女久久久30p| 国产偷久久久精品专区| 一本色综合网久久| 亚洲AV无码成人网站久久精品大| 久久亚洲精品无码VA大香大香 | 一级做a爰片久久毛片人呢| 国产精品毛片久久久久久久| 高清免费久久午夜精品| 久久久久久狠狠丁香|