• <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++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理
            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是一個隨機數(shù),每次客戶端連接上來的時生成一個新的隨機數(shù)(隨著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是由客戶端生成的隨機數(shù),用于本次連接游戲session;serverSeed是SMSG_AUTH_CHALLENGE消息發(fā)過來的服務器隨機數(shù);K是之前和realmd交互做keyexchange時生成的,由服務器和客戶端分別進行計算,SRP6算法要求(保證)兩邊的計算結果一致,服務器端保存在realmd.account.sessionkey字段。

             

             

             

             

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

               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()函數(shù)中使用switch case把客戶端發(fā)過來的不同的opcode定位到不同的處理函數(shù)中,而登錄認證過程需要定位到int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)函數(shù)。

            在HandleAuthSession()函數(shù)中,服務器以客戶端相同的方式計算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之間認證時,各自生成一個隨機數(shù)Seed,保證在傳輸過程中隱藏sessionkey。

            精品久久8x国产免费观看| 94久久国产乱子伦精品免费| 国产精品乱码久久久久久软件| 久久妇女高潮几次MBA| 亚洲人成网亚洲欧洲无码久久| 国产精品久久久久9999| 欧美一级久久久久久久大片| 国产精品久久久久久影院| 久久久久青草线蕉综合超碰| 亚洲中文精品久久久久久不卡| 久久久久久毛片免费看| 久久精品国产久精国产一老狼| 久久精品国产欧美日韩| 欧美一区二区三区久久综合| 久久播电影网| 国产精品熟女福利久久AV| 少妇久久久久久久久久| 久久久久国产精品嫩草影院 | 亚洲精品高清国产一久久| 一级做a爰片久久毛片免费陪| 伊人久久精品线影院| 亚洲色欲久久久综合网| 久久亚洲中文字幕精品一区| 中文字幕一区二区三区久久网站| 99久久精品国产麻豆| 97r久久精品国产99国产精| 久久香综合精品久久伊人| 久久久久亚洲av无码专区喷水 | 9999国产精品欧美久久久久久| 久久精品国产亚洲av影院| 无码人妻少妇久久中文字幕 | 香蕉久久夜色精品升级完成| 亚洲精品乱码久久久久久不卡| 性高湖久久久久久久久AAAAA| 亚洲欧美一级久久精品| 久久国产劲爆AV内射—百度| 久久国产亚洲精品| 久久久久亚洲精品日久生情| 久久国产色AV免费观看| 97r久久精品国产99国产精| 996久久国产精品线观看|