• <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。

            久久国产精品偷99| www亚洲欲色成人久久精品| 亚洲а∨天堂久久精品9966| 欧美日韩精品久久免费| 久久国产精品99国产精| 久久91精品国产91久久小草| 久久精品免费网站网| 久久午夜伦鲁片免费无码| 久久人人超碰精品CAOPOREN| 久久综合香蕉国产蜜臀AV| 久久久久亚洲av成人无码电影 | 国产成年无码久久久免费| 国产精品久久久福利| 香港aa三级久久三级老师2021国产三级精品三级在 | 久久久久无码国产精品不卡| 少妇内射兰兰久久| 久久久久综合国产欧美一区二区| 人妻精品久久无码专区精东影业| 久久久网中文字幕| 一本大道久久a久久精品综合| 亚洲伊人久久精品影院| 久久这里有精品| 九九久久精品国产| 欧美亚洲另类久久综合| 久久久久久九九99精品| 久久妇女高潮几次MBA| 久久久久国产日韩精品网站| 老司机国内精品久久久久| www久久久天天com| 亚洲AV无码1区2区久久| 久久久精品国产免大香伊 | 亚洲精品国产字幕久久不卡| 久久中文字幕视频、最近更新| 国产精品久久久久影院嫩草| 久久综合国产乱子伦精品免费| 成人综合久久精品色婷婷| 中文字幕亚洲综合久久菠萝蜜| 久久久久国产精品嫩草影院| 久久精品免费大片国产大片| 无夜精品久久久久久| 久久热这里只有精品在线观看|