コード例 #1
0
	long SmtMapServerDevice111::WMTSGetCapabilities(void)
	{
		if (NULL == m_pJobData->pMapService)
			return SMT_ERR_FAILURE;

		if (NULL == m_pJobData->pMapService)
			return SMT_ERR_FAILURE;

		SmtLogManager * pLogMgr = SmtLogManager::GetSingletonPtr();
		SmtLog *pLog = pLogMgr->GetLog(MAPSEVER_DEVICE_LOG_NAME);
		if (NULL == pLog)
			return SMT_ERR_FAILURE;

		char szTextBuf[MSVR_BUF_LENGTH_1K];
		memset(szTextBuf,0,MSVR_BUF_LENGTH_1K);

		if (SMT_ERR_NONE == SendBuf(szTextBuf,MSVR_BUF_LENGTH_1K,MSVR_RSP_TEXT))
		{
			return SMT_ERR_NONE;
		}

		return SMT_ERR_FAILURE;
	}
コード例 #2
0
/// Logon Challenge command handler
bool AuthSocket::_HandleLogonChallenge()
{
    DEBUG_LOG("Entering _HandleLogonChallenge");
    if (ibuf.GetLength() < sizeof(sAuthLogonChallenge_C))
        return false;

    ///- Read the first 4 bytes (header) to get the length of the remaining of the packet
    std::vector<uint8> buf;
    buf.resize(4);

    ibuf.Read((char *)&buf[0], 4);

    EndianConvert(*((uint16*)(buf[0])));
    uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size;
    DEBUG_LOG("[AuthChallenge] got header, body is %#04x bytes", remaining);

    if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (ibuf.GetLength() < remaining))
        return false;

    //No big fear of memory outage (size is int16, i.e. < 65536)
    buf.resize(remaining + buf.size() + 1);
    buf[buf.size() - 1] = 0;
    sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0];

    // BigEndian code, nop in little endian case
    // size already converted
    EndianConvert(*((uint32*)(&ch->gamename[0])));
    EndianConvert(ch->build);
    EndianConvert(*((uint32*)(&ch->platform[0])));
    EndianConvert(*((uint32*)(&ch->os[0])));
    EndianConvert(*((uint32*)(&ch->country[0])));
    EndianConvert(ch->timezone_bias);
    EndianConvert(ch->ip);

    ///- Read the remaining of the packet
    ibuf.Read((char *)&buf[4], remaining);
    DEBUG_LOG("[AuthChallenge] got full packet, %#04x bytes", ch->size);
    DEBUG_LOG("[AuthChallenge] name(%d): '%s'", ch->I_len, ch->I);

    ByteBuffer pkt;

    _login = (const char*)ch->I;
    _build = ch->build;

    ///- Normalize account name
    //utf8ToUpperOnlyLatin(_login); -- client already send account in expected form

    //Escape the user login to avoid further SQL injection
    //Memory will be freed on AuthSocket object destruction
    _safelogin = _login;
    loginDatabase.escape_string(_safelogin);

    pkt << (uint8) AUTH_LOGON_CHALLENGE;
    pkt << (uint8) 0x00;

    ///- Verify that this IP is not in the ip_banned table
    // No SQL injection possible (paste the IP address as passed by the socket)
    loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");

    std::string address = GetRemoteAddress();
    loginDatabase.escape_string(address);
    QueryResult *result = loginDatabase.PQuery("SELECT * FROM ip_banned WHERE ip = '%s'",address.c_str());
    if(result)
    {
        pkt << (uint8)REALM_AUTH_ACCOUNT_BANNED;
        sLog.outBasic("[AuthChallenge] Banned ip %s tries to login!",GetRemoteAddress().c_str ());
        delete result;
    }
    else
    {
        ///- Get the account details from the account table
        // No SQL injection (escaped user name)

        result = loginDatabase.PQuery("SELECT sha_pass_hash,id,locked,last_ip,gmlevel,v,s FROM account WHERE username = '******'",_safelogin.c_str ());
        if( result )
        {
            ///- If the IP is 'locked', check that the player comes indeed from the correct IP address
            bool locked = false;
            if((*result)[2].GetUInt8() == 1)                // if ip is locked
            {
                DEBUG_LOG("[AuthChallenge] Account '%s' is locked to IP - '%s'", _login.c_str(), (*result)[3].GetString());
                DEBUG_LOG("[AuthChallenge] Player address is '%s'", GetRemoteAddress().c_str());
                if ( strcmp((*result)[3].GetString(),GetRemoteAddress().c_str()) )
                {
                    DEBUG_LOG("[AuthChallenge] Account IP differs");
                    pkt << (uint8) REALM_AUTH_ACCOUNT_FREEZED;
                    locked=true;
                }
                else
                {
                    DEBUG_LOG("[AuthChallenge] Account IP matches");
                }
            }
            else
            {
                DEBUG_LOG("[AuthChallenge] Account '%s' is not locked to ip", _login.c_str());
            }

            if (!locked)
            {
                //set expired bans to inactive
                loginDatabase.Execute("UPDATE account_banned SET active = 0 WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
                ///- If the account is banned, reject the logon attempt
                QueryResult *banresult = loginDatabase.PQuery("SELECT bandate,unbandate FROM account_banned WHERE id = %u AND active = 1", (*result)[1].GetUInt32());
                if(banresult)
                {
                    if((*banresult)[0].GetUInt64() == (*banresult)[1].GetUInt64())
                    {
                        pkt << (uint8) REALM_AUTH_ACCOUNT_BANNED;
                        sLog.outBasic("[AuthChallenge] Banned account %s tries to login!",_login.c_str ());
                    }
                    else
                    {
                        pkt << (uint8) REALM_AUTH_ACCOUNT_FREEZED;
                        sLog.outBasic("[AuthChallenge] Temporarily banned account %s tries to login!",_login.c_str ());
                    }

                    delete banresult;
                }
                else
                {
                    ///- Get the password from the account table, upper it, and make the SRP6 calculation
                    std::string rI = (*result)[0].GetCppString();

                    ///- Don't calculate (v, s) if there are already some in the database
                    std::string databaseV = (*result)[5].GetCppString();
                    std::string databaseS = (*result)[6].GetCppString();

                    sLog.outDebug("database authentication values: v='%s' s='%s'", databaseV.c_str(), databaseS.c_str());

                    // multiply with 2, bytes are stored as hexstring
                    if(databaseV.size() != s_BYTE_SIZE*2 || databaseS.size() != s_BYTE_SIZE*2)
                        _SetVSFields(rI);
                    else
                    {
                        s.SetHexStr(databaseS.c_str());
                        v.SetHexStr(databaseV.c_str());
                    }

                    b.SetRand(19 * 8);
                    BigNumber gmod = g.ModExp(b, N);
                    B = ((v * 3) + gmod) % N;

                    ASSERT(gmod.GetNumBytes() <= 32);

                    BigNumber unk3;
                    unk3.SetRand(16 * 8);

                    ///- Fill the response packet with the result
                    pkt << uint8(REALM_AUTH_SUCCESS);

                    // B may be calculated < 32B so we force minimal length to 32B
                    pkt.append(B.AsByteArray(32), 32);      // 32 bytes
                    pkt << uint8(1);
                    pkt.append(g.AsByteArray(), 1);
                    pkt << uint8(32);
                    pkt.append(N.AsByteArray(32), 32);
                    pkt.append(s.AsByteArray(), s.GetNumBytes());// 32 bytes
                    pkt.append(unk3.AsByteArray(16), 16);
                    uint8 securityFlags = 0;
                    pkt << uint8(securityFlags);            // security flags (0x0...0x04)

                    if(securityFlags & 0x01)                // PIN input
                    {
                        pkt << uint32(0);
                        pkt << uint64(0) << uint64(0);      // 16 bytes hash?
                    }

                    if(securityFlags & 0x02)                // Matrix input
                    {
                        pkt << uint8(0);
                        pkt << uint8(0);
                        pkt << uint8(0);
                        pkt << uint8(0);
                        pkt << uint64(0);
                    }

                    if(securityFlags & 0x04)                // Security token input
                    {
                        pkt << uint8(1);
                    }

                    uint8 secLevel = (*result)[4].GetUInt8();
                    _accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR;

                    _localizationName.resize(4);
                    for(int i = 0; i < 4; ++i)
                        _localizationName[i] = ch->country[4-i-1];

                    sLog.outBasic("[AuthChallenge] account %s is using '%c%c%c%c' locale (%u)", _login.c_str (), ch->country[3], ch->country[2], ch->country[1], ch->country[0], GetLocaleByName(_localizationName));

                    // user authenticated => turn off autoreg, thus account creating
                    _autoreg = false;
                }
            }
            delete result;
        }
        else if(_autoreg)                                   // no account
        {
            // check username
            if(_safelogin.find_first_of(notAllowedChars)!=_safelogin.npos || _safelogin.length()<4)
                _autoreg = false;
            // check IP
            else if(uint32 amountip = sConfig.GetIntDefault("AmountIP", 0))
            {
                QueryResult *result2 = loginDatabase.PQuery("SELECT COUNT(last_ip) FROM account WHERE last_ip = '%s'", GetRemoteAddress().c_str());
                if (result2 && (*result2)[0].GetUInt8() >= amountip)
                {
                    _autoreg = false;
                    delete result2;
                }
            }

            // still all ok
            if(_autoreg)
            {
                ///- Get the password from the account table, upper it, and make the SRP6 calculation
                std::transform(_safelogin.begin(), _safelogin.end(), _safelogin.begin(), std::towupper);
                Sha1Hash sha;
                std::string sI = _safelogin + ":" + _safelogin;
                sha.UpdateData(sI);
                sha.Finalize();

                BigNumber bn;
                bn.SetBinary(sha.GetDigest(), sha.GetLength());
                uint8 *val = bn.AsByteArray();
                std::reverse(val, val+bn.GetNumBytes());
                bn.SetBinary(val, bn.GetNumBytes());

                const char* rI = bn.AsHexStr();
                _SetVSFields(rI);
                OPENSSL_free((void*)rI);

                b.SetRand(19 * 8);
                BigNumber gmod=g.ModExp(b, N);
                B = ((v * 3) + gmod) % N;

                if (B.GetNumBytes() < 32)
                    sLog.outDetail("Interesting, calculation of B in realmd is < 32.");

                ASSERT(gmod.GetNumBytes() <= 32);

                BigNumber unk3;
                unk3.SetRand(16*8);

                ///- Fill the response packet with the result
                pkt << (uint8)REALM_AUTH_SUCCESS;
                pkt.append(B.AsByteArray(), 32);
                pkt << (uint8)1;
                pkt.append(g.AsByteArray(), 1);
                pkt << (uint8)32;
                pkt.append(N.AsByteArray(), 32);
                pkt.append(s.AsByteArray(), s.GetNumBytes());
                pkt.append(unk3.AsByteArray(), 16);
                pkt << (uint8)0;                // Added in 1.12.x client branch
            }
            else
                // username and/or IP is bad
                pkt << (uint8) REALM_AUTH_NO_MATCH;
        }
        else
        {
            // autoreg off in config, account is wrong
            pkt << (uint8) REALM_AUTH_NO_MATCH;
        }
    }
    SendBuf((char const*)pkt.contents(), pkt.size());
    return true;
}
コード例 #3
0
ファイル: AuthSocket.cpp プロジェクト: Dump/mangos
/// Logon Proof command handler
bool AuthSocket::_HandleLogonProof()
{
    DEBUG_LOG("Entering _HandleLogonProof");
    ///- Read the packet
    if (ibuf.GetLength() < sizeof(sAuthLogonProof_C))
        return false;

    sAuthLogonProof_C lp;
    ibuf.Read((char *)&lp, sizeof(sAuthLogonProof_C));

    ///- Continue the SRP6 calculation based on data received from the client
    BigNumber A;
    A.SetBinary(lp.A, 32);

    Sha1Hash sha;
    sha.UpdateBigNumbers(&A, &B, NULL);
    sha.Finalize();
    BigNumber u;
    u.SetBinary(sha.GetDigest(), 20);
    BigNumber S = (A * (v.ModExp(u, N))).ModExp(b, N);

    uint8 t[32];
    uint8 t1[16];
    uint8 vK[40];
    memcpy(t, S.AsByteArray(), 32);
    for (int i = 0; i < 16; i++)
    {
        t1[i] = t[i*2];
    }
    sha.Initialize();
    sha.UpdateData(t1, 16);
    sha.Finalize();
    for (int i = 0; i < 20; i++)
    {
        vK[i*2] = sha.GetDigest()[i];
    }
    for (int i = 0; i < 16; i++)
    {
        t1[i] = t[i*2+1];
    }
    sha.Initialize();
    sha.UpdateData(t1, 16);
    sha.Finalize();
    for (int i = 0; i < 20; i++)
    {
        vK[i*2+1] = sha.GetDigest()[i];
    }
    K.SetBinary(vK, 40);

    uint8 hash[20];

    sha.Initialize();
    sha.UpdateBigNumbers(&N, NULL);
    sha.Finalize();
    memcpy(hash, sha.GetDigest(), 20);
    sha.Initialize();
    sha.UpdateBigNumbers(&g, NULL);
    sha.Finalize();
    for (int i = 0; i < 20; i++)
    {
        hash[i] ^= sha.GetDigest()[i];
    }
    BigNumber t3;
    t3.SetBinary(hash, 20);

    sha.Initialize();
    sha.UpdateData(_login);
    sha.Finalize();
    uint8 t4[SHA_DIGEST_LENGTH];
    memcpy(t4, sha.GetDigest(), SHA_DIGEST_LENGTH);

    sha.Initialize();
    sha.UpdateBigNumbers(&t3, NULL);
    sha.UpdateData(t4, SHA_DIGEST_LENGTH);
    sha.UpdateBigNumbers(&s, &A, &B, &K, NULL);
    sha.Finalize();
    BigNumber M;
    M.SetBinary(sha.GetDigest(), 20);

    ///- Check if SRP6 results match (password is correct), else send an error
    if (!memcmp(M.AsByteArray(), lp.M1, 20))
    {
        sLog.outBasic("User '%s' successfully authenticated", _login.c_str());

        ///- Update the sessionkey, last_ip, last login time and reset number of failed logins in the account table for this account
        // No SQL injection (escaped user name) and IP address as received by socket
        const char* K_hex = K.AsHexStr();
        dbRealmServer.PExecute("UPDATE account SET sessionkey = '%s', last_ip = '%s', last_login = NOW(), locale = '%u', failed_logins = 0 WHERE username = '******'", K_hex, GetRemoteAddress().c_str(),  _localization, _safelogin.c_str() );
        OPENSSL_free((void*)K_hex);

        ///- Finish SRP6 and send the final result to the client
        sha.Initialize();
        sha.UpdateBigNumbers(&A, &M, &K, NULL);
        sha.Finalize();

        sAuthLogonProof_S proof;
        memcpy(proof.M2, sha.GetDigest(), 20);
        proof.cmd = AUTH_LOGON_PROOF;
        proof.error = 0;
        proof.unk1 = 0x00800000;
        proof.unk2 = 0x00;
        proof.unk3 = 0x00;

        SendBuf((char *)&proof, sizeof(proof));

        ///- Set _authed to true!
        _authed = true;
    }
    else
    {
        char data[4]={AUTH_LOGON_PROOF,REALM_AUTH_NO_MATCH,3,0};
        SendBuf(data,sizeof(data));
        sLog.outBasic("[AuthChallenge] account %s tried to login with wrong password!",_login.c_str ());

        uint32 MaxWrongPassCount = sConfig.GetIntDefault("WrongPass.MaxCount", 0);
        if(MaxWrongPassCount > 0)
        {
            //Increment number of failed logins by one and if it reaches the limit temporarily ban that account or IP
            dbRealmServer.PExecute("UPDATE account SET failed_logins = failed_logins + 1 WHERE username = '******'",_safelogin.c_str());

            if(QueryResult *loginfail = dbRealmServer.PQuery("SELECT id, failed_logins FROM account WHERE username = '******'", _safelogin.c_str()))
            {
                Field* fields = loginfail->Fetch();
                uint32 failed_logins = fields[1].GetUInt32();

                if( failed_logins >= MaxWrongPassCount )
                {
                    uint32 WrongPassBanTime = sConfig.GetIntDefault("WrongPass.BanTime", 600);
                    bool WrongPassBanType = sConfig.GetBoolDefault("WrongPass.BanType", false);

                    if(WrongPassBanType)
                    {
                        uint32 acc_id = fields[0].GetUInt32();
                        dbRealmServer.PExecute("INSERT INTO account_banned VALUES ('%u',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','MaNGOS realmd','Failed login autoban',1)",
                            acc_id, WrongPassBanTime);
                        sLog.outBasic("[AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times",
                            _login.c_str(), WrongPassBanTime, failed_logins);
                    }
                    else
                    {
                        std::string current_ip = GetRemoteAddress();
                        dbRealmServer.escape_string(current_ip);
                        dbRealmServer.PExecute("INSERT INTO ip_banned VALUES ('%s',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','MaNGOS realmd','Failed login autoban')",
                            current_ip.c_str(), WrongPassBanTime);
                        sLog.outBasic("[AuthChallenge] IP %s got banned for '%u' seconds because account %s failed to authenticate '%u' times",
                            current_ip.c_str(), WrongPassBanTime, _login.c_str(), failed_logins);
                    }
                }
                delete loginfail;
            }
        }
    }
    return true;
}
コード例 #4
0
ファイル: AuthSocket.cpp プロジェクト: Dump/mangos
/// Logon Challenge command handler
bool AuthSocket::_HandleLogonChallenge()
{
    DEBUG_LOG("Entering _HandleLogonChallenge");
    if (ibuf.GetLength() < sizeof(sAuthLogonChallenge_C))
        return false;

    ///- Read the first 4 bytes (header) to get the length of the remaining of the packet
    std::vector<uint8> buf;
    buf.resize(4);

    ibuf.Read((char *)&buf[0], 4);

    EndianConvert(*((uint16*)(buf[0])));
    uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size;
    DEBUG_LOG("[AuthChallenge] got header, body is %#04x bytes", remaining);

    if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (ibuf.GetLength() < remaining))
        return false;

    //No big fear of memory outage (size is int16, i.e. < 65536)
    buf.resize(remaining + buf.size() + 1);
    buf[buf.size() - 1] = 0;
    sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0];

    // BigEndian code, nop in little endian case
    // size already converted
    EndianConvert(*((uint32*)(&ch->gamename[0])));
    EndianConvert(ch->build);
    EndianConvert(*((uint32*)(&ch->platform[0])));
    EndianConvert(*((uint32*)(&ch->os[0])));
    EndianConvert(*((uint32*)(&ch->country[0])));
    EndianConvert(ch->timezone_bias);
    EndianConvert(ch->ip);

    ///- Read the remaining of the packet
    ibuf.Read((char *)&buf[4], remaining);
    DEBUG_LOG("[AuthChallenge] got full packet, %#04x bytes", ch->size);
    DEBUG_LOG("[AuthChallenge] name(%d): '%s'", ch->I_len, ch->I);

    ByteBuffer pkt;

    _login = (const char*)ch->I;

    ///- Normalize account name
    //utf8ToUpperOnlyLatin(_login); -- client already send account in expected form

    //Escape the user login to avoid further SQL injection
    //Memory will be freed on AuthSocket object destruction
    _safelogin=_login;
    dbRealmServer.escape_string(_safelogin);

    ///- Check if the client has one of the expected version numbers
    bool valid_version=false;
    int accepted_versions[]=EXPECTED_MANGOS_CLIENT_BUILD;
    for(int i=0;accepted_versions[i];i++)
        if(ch->build==accepted_versions[i])
    {
        valid_version=true;
        break;
    }

    /// <ul><li> if this is a valid version
    if(valid_version)
    {
        pkt << (uint8) AUTH_LOGON_CHALLENGE;
        pkt << (uint8) 0x00;

        ///- Verify that this IP is not in the ip_banned table
        // No SQL injection possible (paste the IP address as passed by the socket)
        dbRealmServer.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");

        std::string address = GetRemoteAddress();
        dbRealmServer.escape_string(address);
        QueryResult *result = dbRealmServer.PQuery(  "SELECT * FROM ip_banned WHERE ip = '%s'",address.c_str());
        if(result)
        {
            pkt << (uint8)REALM_AUTH_ACCOUNT_BANNED;
            sLog.outBasic("[AuthChallenge] Banned ip %s tries to login!",GetRemoteAddress().c_str ());
            delete result;
        }
        else
        {
            ///- Get the account details from the account table
            // No SQL injection (escaped user name)

            result = dbRealmServer.PQuery("SELECT sha_pass_hash,id,locked,last_ip,gmlevel FROM account WHERE username = '******'",_safelogin.c_str ());
            if( result )
            {
                ///- If the IP is 'locked', check that the player comes indeed from the correct IP address
                bool locked = false;
                if((*result)[2].GetUInt8() == 1)            // if ip is locked
                {
                    DEBUG_LOG("[AuthChallenge] Account '%s' is locked to IP - '%s'", _login.c_str(), (*result)[3].GetString());
                    DEBUG_LOG("[AuthChallenge] Player address is '%s'", GetRemoteAddress().c_str());
                    if ( strcmp((*result)[3].GetString(),GetRemoteAddress().c_str()) )
                    {
                        DEBUG_LOG("[AuthChallenge] Account IP differs");
                        pkt << (uint8) REALM_AUTH_ACCOUNT_FREEZED;
                        locked=true;
                    }
                    else
                    {
                        DEBUG_LOG("[AuthChallenge] Account IP matches");
                    }
                }
                else
                {
                    DEBUG_LOG("[AuthChallenge] Account '%s' is not locked to ip", _login.c_str());
                }

                if (!locked)
                {
                    //set expired bans to inactive
                    dbRealmServer.Execute("UPDATE account_banned SET active = 0 WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
                    ///- If the account is banned, reject the logon attempt
                    QueryResult *banresult = dbRealmServer.PQuery("SELECT bandate,unbandate FROM account_banned WHERE id = %u AND active = 1", (*result)[1].GetUInt32());
                    if(banresult)
                    {
                        if((*banresult)[0].GetUInt64() == (*banresult)[1].GetUInt64())
                        {
                            pkt << (uint8) REALM_AUTH_ACCOUNT_BANNED;
                            sLog.outBasic("[AuthChallenge] Banned account %s tries to login!",_login.c_str ());
                        }
                        else
                        {
                            pkt << (uint8) REALM_AUTH_ACCOUNT_FREEZED;
                            sLog.outBasic("[AuthChallenge] Temporarily banned account %s tries to login!",_login.c_str ());
                        }

                        delete banresult;
                    }
                    else
                    {
                        ///- Get the password from the account table, upper it, and make the SRP6 calculation
                        std::string rI = (*result)[0].GetCppString();
                        _SetVSFields(rI);

                        b.SetRand(19 * 8);
                        BigNumber gmod=g.ModExp(b, N);
                        B = ((v * 3) + gmod) % N;

                        ASSERT(gmod.GetNumBytes() <= 32);

                        BigNumber unk3;
                        unk3.SetRand(16*8);

                        ///- Fill the response packet with the result
                        pkt << (uint8)REALM_AUTH_SUCCESS;

                        // B may be calculated < 32B so we force minnimal length to 32B
                        pkt.append(B.AsByteArray(32), 32);   // 32 bytes
                        pkt << (uint8)1;
                        pkt.append(g.AsByteArray(), 1);
                        pkt << (uint8)32;
                        pkt.append(N.AsByteArray(), 32);
                        pkt.append(s.AsByteArray(), s.GetNumBytes());   // 32 bytes
                        pkt.append(unk3.AsByteArray(), 16);
                        pkt << (uint8)0;                    // Added in 1.12.x client branch

                        uint8 secLevel = (*result)[4].GetUInt8();
                        _accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR;

                        std::string localeName;
                        localeName.resize(4);
                        for(int i = 0; i <4; ++i)
                            localeName[i] = ch->country[4-i-1];

                        _localization = GetLocaleByName(localeName);

                        sLog.outBasic("[AuthChallenge] account %s is using '%c%c%c%c' locale (%u)", _login.c_str (), ch->country[3],ch->country[2],ch->country[1],ch->country[0], _localization);
                    }
                }
                delete result;
            }
            else                                            //no account
            {
                pkt<< (uint8) REALM_AUTH_NO_MATCH;
            }
        }
    }                                                       //valid version
    else
        ///<li> else
    {
        ///- Check if we have the apropriate patch on the disk
        char tmp[64];
        // No buffer overflow (fixed length of arguments)
        sprintf(tmp,"./patches/%d%c%c%c%c.mpq",ch->build,ch->country[3],
            ch->country[2],ch->country[1],ch->country[0]);
        // This will be closed at the destruction of the AuthSocket (client deconnection)
        FILE *pFile=fopen(tmp,"rb");
        if(!pFile)
        {
            pkt << (uint8) AUTH_LOGON_CHALLENGE;
            pkt << (uint8) 0x00;
            pkt << (uint8) REALM_AUTH_WRONG_BUILD_NUMBER;
            DEBUG_LOG("[AuthChallenge] %u is not a valid client version!", ch->build);
            DEBUG_LOG("[AuthChallenge] Patch %s not found",tmp);
        }else
        {                                                   //have patch
            pPatch=pFile;
            XFER_INIT xferh;

            ///- Get the MD5 hash of the patch file (get it from preloaded Patcher cache or calculate it)
            if(PatchesCache.GetHash(tmp,(uint8*)&xferh.md5))
            {
                DEBUG_LOG("\n[AuthChallenge] Found precached patch info for patch %s",tmp);
            }
            else
            {                                               //calculate patch md5
                printf("\n[AuthChallenge] Patch info for %s was not cached.",tmp);
                PatchesCache.LoadPatchMD5(tmp);
                PatchesCache.GetHash(tmp,(uint8*)&xferh.md5);
            }

            ///- Send a packet to the client with the file length and MD5 hash
            uint8 data[2]={AUTH_LOGON_PROOF,REALM_AUTH_UPDATE_CLIENT};
            SendBuf((const char*)data,sizeof(data));

            memcpy(&xferh,"0\x05Patch",7);
            xferh.cmd=XFER_INITIATE;
            fseek(pPatch,0,SEEK_END);
            xferh.file_size=ftell(pPatch);

            SendBuf((const char*)&xferh,sizeof(xferh));
            return true;
        }
    }
    /// </ul>
    SendBuf((char const*)pkt.contents(), pkt.size());
    return true;
}
コード例 #5
0
ファイル: AuthSocket.cpp プロジェクト: 801616/mangos
/// Logon Challenge command handler
bool AuthSocket::_HandleLogonChallenge()
{
    DEBUG_LOG("Entering _HandleLogonChallenge");
    if (ibuf.GetLength() < sizeof(sAuthLogonChallenge_C))
        return false;

    ///- Read the first 4 bytes (header) to get the length of the remaining of the packet
    std::vector<uint8> buf;
    buf.resize(4);

    ibuf.Read((char *)&buf[0], 4);

    EndianConvert(*((uint16*)(buf[0])));
    uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size;
    DEBUG_LOG("[AuthChallenge] got header, body is %#04x bytes", remaining);

    if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (ibuf.GetLength() < remaining))
        return false;

    //No big fear of memory outage (size is int16, i.e. < 65536)
    buf.resize(remaining + buf.size() + 1);
    buf[buf.size() - 1] = 0;
    sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0];

    // BigEndian code, nop in little endian case
    // size already converted
    EndianConvert(*((uint32*)(&ch->gamename[0])));
    EndianConvert(ch->build);
    EndianConvert(*((uint32*)(&ch->platform[0])));
    EndianConvert(*((uint32*)(&ch->os[0])));
    EndianConvert(*((uint32*)(&ch->country[0])));
    EndianConvert(ch->timezone_bias);
    EndianConvert(ch->ip);

    ///- Read the remaining of the packet
    ibuf.Read((char *)&buf[4], remaining);
    DEBUG_LOG("[AuthChallenge] got full packet, %#04x bytes", ch->size);
    DEBUG_LOG("[AuthChallenge] name(%d): '%s'", ch->I_len, ch->I);

    ByteBuffer pkt;

    _login = (const char*)ch->I;
    _build = ch->build;

    ///- Normalize account name
    //utf8ToUpperOnlyLatin(_login); -- client already send account in expected form

    //Escape the user login to avoid further SQL injection
    //Memory will be freed on AuthSocket object destruction
    _safelogin=_login;
    dbRealmServer.escape_string(_safelogin);

    pkt << (uint8) AUTH_LOGON_CHALLENGE;
    pkt << (uint8) 0x00;

    ///- Verify that this IP is not in the ip_banned table
    // No SQL injection possible (paste the IP address as passed by the socket)
    dbRealmServer.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");

    std::string address = GetRemoteAddress();
    dbRealmServer.escape_string(address);
    QueryResult *result = dbRealmServer.PQuery(  "SELECT * FROM ip_banned WHERE ip = '%s'",address.c_str());
    if(result)
    {
        pkt << (uint8)REALM_AUTH_ACCOUNT_BANNED;
        sLog.outBasic("[AuthChallenge] Banned ip %s tries to login!",GetRemoteAddress().c_str ());
        delete result;
    }
    else
    {
        ///- Get the account details from the account table
        // No SQL injection (escaped user name)

        result = dbRealmServer.PQuery("SELECT sha_pass_hash,id,locked,last_ip,gmlevel FROM account WHERE username = '******'",_safelogin.c_str ());
        if( result )
        {
            ///- If the IP is 'locked', check that the player comes indeed from the correct IP address
            bool locked = false;
            if((*result)[2].GetUInt8() == 1)            // if ip is locked
            {
                DEBUG_LOG("[AuthChallenge] Account '%s' is locked to IP - '%s'", _login.c_str(), (*result)[3].GetString());
                DEBUG_LOG("[AuthChallenge] Player address is '%s'", GetRemoteAddress().c_str());
                if ( strcmp((*result)[3].GetString(),GetRemoteAddress().c_str()) )
                {
                    DEBUG_LOG("[AuthChallenge] Account IP differs");
                    pkt << (uint8) REALM_AUTH_ACCOUNT_FREEZED;
                    locked=true;
                }
                else
                {
                    DEBUG_LOG("[AuthChallenge] Account IP matches");
                }
            }
            else
            {
                DEBUG_LOG("[AuthChallenge] Account '%s' is not locked to ip", _login.c_str());
            }

            if (!locked)
            {
                //set expired bans to inactive
                dbRealmServer.Execute("UPDATE account_banned SET active = 0 WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
                ///- If the account is banned, reject the logon attempt
                QueryResult *banresult = dbRealmServer.PQuery("SELECT bandate,unbandate FROM account_banned WHERE id = %u AND active = 1", (*result)[1].GetUInt32());
                if(banresult)
                {
                    if((*banresult)[0].GetUInt64() == (*banresult)[1].GetUInt64())
                    {
                        pkt << (uint8) REALM_AUTH_ACCOUNT_BANNED;
                        sLog.outBasic("[AuthChallenge] Banned account %s tries to login!",_login.c_str ());
                    }
                    else
                    {
                        pkt << (uint8) REALM_AUTH_ACCOUNT_FREEZED;
                        sLog.outBasic("[AuthChallenge] Temporarily banned account %s tries to login!",_login.c_str ());
                    }

                    delete banresult;
                }
                else
                {
                    ///- Get the password from the account table, upper it, and make the SRP6 calculation
                    std::string rI = (*result)[0].GetCppString();
                    _SetVSFields(rI);

                    b.SetRand(19 * 8);
                    BigNumber gmod=g.ModExp(b, N);
                    B = ((v * 3) + gmod) % N;

                    ASSERT(gmod.GetNumBytes() <= 32);

                    BigNumber unk3;
                    unk3.SetRand(16*8);

                    ///- Fill the response packet with the result
                    pkt << (uint8)REALM_AUTH_SUCCESS;

                    // B may be calculated < 32B so we force minnimal length to 32B
                    pkt.append(B.AsByteArray(32), 32);   // 32 bytes
                    pkt << (uint8)1;
                    pkt.append(g.AsByteArray(), 1);
                    pkt << (uint8)32;
                    pkt.append(N.AsByteArray(), 32);
                    pkt.append(s.AsByteArray(), s.GetNumBytes());   // 32 bytes
                    pkt.append(unk3.AsByteArray(), 16);
                    pkt << (uint8)0;                    // Added in 1.12.x client branch

                    uint8 secLevel = (*result)[4].GetUInt8();
                    _accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR;

                    _localizationName.resize(4);
                    for(int i = 0; i <4; ++i)
                        _localizationName[i] = ch->country[4-i-1];

                    sLog.outBasic("[AuthChallenge] account %s is using '%c%c%c%c' locale (%u)", _login.c_str (), ch->country[3],ch->country[2],ch->country[1],ch->country[0], GetLocaleByName(_localizationName));
                }
            }
            delete result;
        }
        else                                            //no account
        {
            pkt<< (uint8) REALM_AUTH_NO_MATCH;
        }
    }
    SendBuf((char const*)pkt.contents(), pkt.size());
    return true;
}
コード例 #6
0
ファイル: ControlSocket.cpp プロジェクト: Cyph3r/pseuwow
void ControlSocket::SendTelnetText(std::string s)
{
    s += "\n\r";
    SendBuf(s.c_str(),s.size());
}
コード例 #7
0
ファイル: AuthSocket.cpp プロジェクト: Artea/mangos-svn
/// %Realm List command handler
bool AuthSocket::_HandleRealmList()
{
    DEBUG_LOG("Entering _HandleRealmList");
    if (ibuf.GetLength() < 5)
        return false;

    ibuf.Remove(5);

    ///- Get the user id (else close the connection)
    // No SQL injection (escaped user name)

    QueryResult *result = dbRealmServer.PQuery("SELECT `id`,`I` FROM `account` WHERE `username` = '%s'",_safelogin.c_str());
    if(!result)
    {
        sLog.outError("[ERROR] user %s tried to login and we cannot find him in the database.",_login.c_str());
        this->Close();
        return false;
    }

    uint32 id = (*result)[0].GetUInt32();
    std::string rI = (*result)[1].GetCppString();
    delete result;

    ///- Circle through realms in the RealmList and construct the return packet (including # of user characters in each realm)
    uint8 AmountOfCharacters = 0;

    ByteBuffer pkt;
    pkt << (uint32) 0;
    pkt << (uint16) m_realmList.size();
    RealmList::RealmMap::const_iterator i;
    for( i = m_realmList.begin(); i != m_realmList.end(); i++ )
    {
        pkt << i->second->icon;                             // realm type
        pkt << (uint8) 0;                                   // if 1, then realm locked
        pkt << i->second->color;                            // if 2, then realm is offline
        pkt << i->first;
        pkt << i->second->address;
        /// \todo Fix realm population
        pkt << (float) 0.0;                                 //this is population 0.5 = low 1.0 = medium 2.0 high     (float)(maxplayers / players)*2
        // No SQL injection. id of realm is controlled by the database.
        result = dbRealmServer.PQuery( "SELECT `numchars` FROM `realmcharacters` WHERE `realmid` = '%d' AND `acctid`='%u'",i->second->m_ID,id);
        if( result )
        {
            Field *fields = result->Fetch();
            AmountOfCharacters = fields[0].GetUInt8();
            delete result;
        }
        pkt << AmountOfCharacters;
        pkt << i->second->timezone;
        pkt << (uint8) 0x2C;                                // unk, may be realm number/id?
    }
    pkt << (uint8) 0x10;
    pkt << (uint8) 0x00;

    ByteBuffer hdr;
    hdr << (uint8) REALM_LIST;
    hdr << (uint16)pkt.size();
    hdr.append(pkt);

    SendBuf((char *)hdr.contents(), hdr.size());

    // Set check field before possable relogin to realm
    _SetVSFields(rI);
    return true;
}
コード例 #8
0
ファイル: AuthSocket.cpp プロジェクト: X-Core/X-core-addons
/// Logon Proof command handler
bool AuthSocket::_HandleLogonProof()
{
    DEBUG_LOG("Entering _HandleLogonProof");
    ///- Read the packet
    if (ibuf.GetLength() < sizeof(sAuthLogonProof_C))
        return false;
    sAuthLogonProof_C lp;
    ibuf.Read((char *)&lp, sizeof(sAuthLogonProof_C));

    ///- Check if the client has one of the expected version numbers
    bool valid_version = FindBuildInfo(_build) != NULL;

    /// <ul><li> If the client has no valid version
    /// Ignore if its trial client account
    if(!valid_version && !_isTrial)
    {
        ///- Check if we have the apropriate patch on the disk

        // 24 = len("./patches/65535enGB.mpq")+1
        char tmp[24];
        // No buffer overflow (fixed length of arguments)
        sprintf(tmp, "./patches/%d%s.mpq", _build, _localizationName.c_str());
        // This will be closed at the destruction of the AuthSocket (client disconnection)
        FILE *pFile = fopen(tmp, "rb");

        if(!pFile)
        {
            ByteBuffer pkt;
            pkt << (uint8) AUTH_LOGON_CHALLENGE;
            pkt << (uint8) 0x00;
            pkt << (uint8) WOW_FAIL_VERSION_INVALID;
            DEBUG_LOG("[AuthChallenge] %u is not a valid client version!", _build);
            DEBUG_LOG("[AuthChallenge] Patch %s not found", tmp);
            SendBuf((char const*)pkt.contents(), pkt.size());
            return true;
        }
        else                                                // have patch
        {
            pPatch = pFile;
            XFER_INIT xferh;

            ///- Get the MD5 hash of the patch file (get it from preloaded Patcher cache or calculate it)
            if(PatchesCache.GetHash(tmp, (uint8*)&xferh.md5))
            {
                DEBUG_LOG("\n[AuthChallenge] Found precached patch info for patch %s", tmp);
            }
            else
            {                                               // calculate patch md5
                printf("\n[AuthChallenge] Patch info for %s was not cached.", tmp);
                PatchesCache.LoadPatchMD5(tmp);
                PatchesCache.GetHash(tmp, (uint8*)&xferh.md5);
            }

            ///- Send a packet to the client with the file length and MD5 hash
            uint8 data[2] = { AUTH_LOGON_PROOF, WOW_FAIL_VERSION_UPDATE };
            SendBuf((const char*)data, sizeof(data));

            memcpy(&xferh, "0\x05Patch", 7);
            xferh.cmd = XFER_INITIATE;
            fseek(pPatch, 0, SEEK_END);
            xferh.file_size = ftell(pPatch);

            SendBuf((const char*)&xferh, sizeof(xferh));
            return true;
        }
    }
    /// </ul>

    ///- Continue the SRP6 calculation based on data received from the client
    BigNumber A;

    A.SetBinary(lp.A, 32);

    // SRP safeguard: abort if A==0
    if (A.isZero())
        return false;

    Sha1Hash sha;
    sha.UpdateBigNumbers(&A, &B, NULL);
    sha.Finalize();
    BigNumber u;
    u.SetBinary(sha.GetDigest(), 20);
    BigNumber S = (A * (v.ModExp(u, N))).ModExp(b, N);

    uint8 t[32];
    uint8 t1[16];
    uint8 vK[40];
    memcpy(t, S.AsByteArray(32), 32);
    for (int i = 0; i < 16; ++i)
    {
        t1[i] = t[i * 2];
    }
    sha.Initialize();
    sha.UpdateData(t1, 16);
    sha.Finalize();
    for (int i = 0; i < 20; ++i)
    {
        vK[i * 2] = sha.GetDigest()[i];
    }
    for (int i = 0; i < 16; ++i)
    {
        t1[i] = t[i * 2 + 1];
    }
    sha.Initialize();
    sha.UpdateData(t1, 16);
    sha.Finalize();
    for (int i = 0; i < 20; ++i)
    {
        vK[i * 2 + 1] = sha.GetDigest()[i];
    }
    K.SetBinary(vK, 40);

    uint8 hash[20];

    sha.Initialize();
    sha.UpdateBigNumbers(&N, NULL);
    sha.Finalize();
    memcpy(hash, sha.GetDigest(), 20);
    sha.Initialize();
    sha.UpdateBigNumbers(&g, NULL);
    sha.Finalize();
    for (int i = 0; i < 20; ++i)
    {
        hash[i] ^= sha.GetDigest()[i];
    }
    BigNumber t3;
    t3.SetBinary(hash, 20);

    sha.Initialize();
    sha.UpdateData(_login);
    sha.Finalize();
    uint8 t4[SHA_DIGEST_LENGTH];
    memcpy(t4, sha.GetDigest(), SHA_DIGEST_LENGTH);

    sha.Initialize();
    sha.UpdateBigNumbers(&t3, NULL);
    sha.UpdateData(t4, SHA_DIGEST_LENGTH);
    sha.UpdateBigNumbers(&s, &A, &B, &K, NULL);
    sha.Finalize();
    BigNumber M;
    M.SetBinary(sha.GetDigest(), 20);

    ///- Check if SRP6 results match (password is correct), else send an error
    if (!memcmp(M.AsByteArray(), lp.M1, 20))
    {
        BASIC_LOG("User '%s' successfully authenticated", _login.c_str());

        ///- Update the sessionkey, last_ip, last login time and reset number of failed logins in the account table for this account
        // No SQL injection (escaped user name) and IP address as received by socket
        const char* K_hex = K.AsHexStr();
        loginDatabase.PExecute("UPDATE account SET sessionkey = '%s', last_ip = '%s', last_login = NOW(), locale = '%u', failed_logins = 0 WHERE username = '******'", K_hex, GetRemoteAddress().c_str(), GetLocaleByName(_localizationName), _safelogin.c_str() );
        OPENSSL_free((void*)K_hex);

        ///- Finish SRP6 and send the final result to the client
        sha.Initialize();
        sha.UpdateBigNumbers(&A, &M, &K, NULL);
        sha.Finalize();

        SendProof(sha);

        ///- Set _authed to true!
        _authed = true;
    }
    else
    {
        char data[4]= { AUTH_LOGON_PROOF, WOW_FAIL_UNKNOWN_ACCOUNT, 3, 0};
        SendBuf(data, sizeof(data));
        BASIC_LOG("[AuthChallenge] account %s tried to login with wrong password!",_login.c_str ());

        uint32 MaxWrongPassCount = sConfig.GetIntDefault("WrongPass.MaxCount", 0);
        if(MaxWrongPassCount > 0)
        {
            //Increment number of failed logins by one and if it reaches the limit temporarily ban that account or IP
            loginDatabase.PExecute("UPDATE account SET failed_logins = failed_logins + 1 WHERE username = '******'",_safelogin.c_str());

            if(QueryResult *loginfail = loginDatabase.PQuery("SELECT id, failed_logins FROM account WHERE username = '******'", _safelogin.c_str()))
            {
                Field* fields = loginfail->Fetch();
                uint32 failed_logins = fields[1].GetUInt32();

                if( failed_logins >= MaxWrongPassCount )
                {
                    uint32 WrongPassBanTime = sConfig.GetIntDefault("WrongPass.BanTime", 600);
                    bool WrongPassBanType = sConfig.GetBoolDefault("WrongPass.BanType", false);

                    if(WrongPassBanType)
                    {
                        uint32 acc_id = fields[0].GetUInt32();
                        loginDatabase.PExecute("INSERT INTO account_banned VALUES ('%u',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','MaNGOS realmd','Failed login autoban',1)",
                            acc_id, WrongPassBanTime);
                        BASIC_LOG("[AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times",
                            _login.c_str(), WrongPassBanTime, failed_logins);
                    }
                    else
                    {
                        std::string current_ip = GetRemoteAddress();
                        loginDatabase.escape_string(current_ip);
                        loginDatabase.PExecute("INSERT INTO ip_banned VALUES ('%s',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','MaNGOS realmd','Failed login autoban')",
                            current_ip.c_str(), WrongPassBanTime);
                        BASIC_LOG("[AuthChallenge] IP %s got banned for '%u' seconds because account %s failed to authenticate '%u' times",
                            current_ip.c_str(), WrongPassBanTime, _login.c_str(), failed_logins);
                    }
                }
                delete loginfail;
            }
        }
    }
    return true;
}
コード例 #9
0
ファイル: Ajp13Socket.cpp プロジェクト: amirkrifa/BitHoc
// --------------------------------------------------------------------------------------
void Ajp13Socket::Respond(const HttpResponse& res)
{
    char msg[8192];
    msg[0] = 'A';
    msg[1] = 'B';

    m_res = res;

// reply codes
//	0x3 Send Body Chunk
//	0x4 Send Headers
//	0x5 End Response
//	0x6 Get Body Chunk
//	0x9 CPong Reply

    // check content length
    if (!m_res.ContentLength() && m_res.GetFile().size())
    {
//		m_res.SetContentLength( m_res.GetFile().size() );
    }

    // Send Headers
    {
        int ptr = 4;
        put_byte(msg, ptr, 0x04); // send headers
        put_integer(msg, ptr, m_res.HttpStatusCode() );
        put_string(msg, ptr, m_res.HttpStatusMsg() );
        put_integer(msg, ptr, (short)m_res.Headers().size() );
        for (Utility::ncmap<std::string>::const_iterator it = m_res.Headers().begin(); it != m_res.Headers().end(); ++it)
        {
            Utility::ncmap<int>::const_iterator it2 = Init.ResponseHeader.find( it -> first );
            if (it2 != Init.ResponseHeader.end())
            {
                put_integer(msg, ptr, it2 -> second);
            }
            else
            {
                put_string(msg, ptr, it -> first);
            }
            put_string(msg, ptr, it -> second);
        }
        std::list<std::string> vec = m_res.CookieNames();
        {
            for (std::list<std::string>::iterator it = vec.begin(); it != vec.end(); it++)
            {
                Utility::ncmap<int>::const_iterator it2 = Init.ResponseHeader.find( "set-cookie" );
                if (it2 != Init.ResponseHeader.end())
                {
                    put_integer(msg, ptr, it2 -> second);
                }
                else
                {
                    put_string(msg, ptr, "set-cookie");
                }
                put_string(msg, ptr, m_res.Cookie(*it) );
            }
        }

        short len = htons( ptr - 4 );
        memcpy( msg + 2, &len, 2 );

        SendBuf( msg, ptr );
    }
    // Send Body Chunk
    OnTransferLimit();
}
コード例 #10
0
ファイル: AuthSocket.cpp プロジェクト: Artea/mangos-svn
/// Logon Proof command handler
bool AuthSocket::_HandleLogonProof()
{
    DEBUG_LOG("Entering _HandleLogonProof");
    ///- Read the packet
    if (ibuf.GetLength() < sizeof(sAuthLogonProof_C))
        return false;

    sAuthLogonProof_C lp;
    ibuf.Read((char *)&lp, sizeof(sAuthLogonProof_C));

    ///- Continue the SRP6 calculation based on data received from the client
    BigNumber A;
    A.SetBinary(lp.A, 32);

    Sha1Hash sha;
    sha.UpdateBigNumbers(&A, &B, NULL);
    sha.Finalize();
    BigNumber u;
    u.SetBinary(sha.GetDigest(), 20);
    BigNumber S = (A * (v.ModExp(u, N))).ModExp(b, N);

    uint8 t[32];
    uint8 t1[16];
    uint8 vK[40];
    memcpy(t, S.AsByteArray(), 32);
    for (int i = 0; i < 16; i++)
    {
        t1[i] = t[i*2];
    }
    sha.Initialize();
    sha.UpdateData(t1, 16);
    sha.Finalize();
    for (int i = 0; i < 20; i++)
    {
        vK[i*2] = sha.GetDigest()[i];
    }
    for (int i = 0; i < 16; i++)
    {
        t1[i] = t[i*2+1];
    }
    sha.Initialize();
    sha.UpdateData(t1, 16);
    sha.Finalize();
    for (int i = 0; i < 20; i++)
    {
        vK[i*2+1] = sha.GetDigest()[i];
    }
    K.SetBinary(vK, 40);

    uint8 hash[20];

    sha.Initialize();
    sha.UpdateBigNumbers(&N, NULL);
    sha.Finalize();
    memcpy(hash, sha.GetDigest(), 20);
    sha.Initialize();
    sha.UpdateBigNumbers(&g, NULL);
    sha.Finalize();
    for (int i = 0; i < 20; i++)
    {
        hash[i] ^= sha.GetDigest()[i];
    }
    BigNumber t3;
    t3.SetBinary(hash, 20);

    sha.Initialize();
    sha.UpdateData(_login);
    sha.Finalize();
    BigNumber t4;
    t4.SetBinary(sha.GetDigest(), 20);

    sha.Initialize();
    sha.UpdateBigNumbers(&t3, &t4, &s, &A, &B, &K, NULL);
    sha.Finalize();
    BigNumber M;
    M.SetBinary(sha.GetDigest(), 20);

    ///- Check if SRP6 results match (password is correct), else send an error
    if (!memcmp(M.AsByteArray(), lp.M1, 20))
    {
        sLog.outBasic("User '%s' successfully authenticated", _login.c_str());

        ///- Update the sessionkey, last_ip and last login time in the account table for this account
        // No SQL injection (escaped user name) and IP address as received by socket
        dbRealmServer.PExecute("UPDATE `account` SET `sessionkey` = '%s', `last_ip` = '%s', `last_login` = NOW(), `locale` = '%u' WHERE `username` = '%s'",K.AsHexStr(), GetRemoteAddress().c_str(),  _localization, _safelogin.c_str() );

        ///- Finish SRP6 and send the final result to the client
        sha.Initialize();
        sha.UpdateBigNumbers(&A, &M, &K, NULL);
        sha.Finalize();

        sAuthLogonProof_S proof;
        memcpy(proof.M2, sha.GetDigest(), 20);
        proof.cmd = AUTH_LOGON_PROOF;
        proof.error = 0;
        proof.unk2 = 0;
        proof.unk3 = 0;

        SendBuf((char *)&proof, sizeof(proof));

        ///- Set _authed to true!
        _authed = true;
    }
    else
    {
        char data[4]={AUTH_LOGON_PROOF,REALM_AUTH_NO_MATCH,3,0};
        SendBuf(data,sizeof(data));
    }
    return true;
}
コード例 #11
0
ファイル: packet_example.c プロジェクト: zhu-edward/USV_code
int an_packet_transmit(an_packet_t *an_packet)
{
	an_packet_encode(an_packet);
	return SendBuf(an_packet_pointer(an_packet), an_packet_size(an_packet));
}
コード例 #12
0
ファイル: UdpSocket.cpp プロジェクト: f059074251/interested
void UdpSocket::Send(const std::string& str, int flags)
{
	SendBuf(str.c_str(), (int)str.size(), flags);
}
コード例 #13
0
ファイル: echoserver.cpp プロジェクト: JerkWisdom/zpublic
 void OnRawData(const char *buf,size_t len) {
     if (g_b_nobuf)
     {
         SendBuf(buf, len);
     }
 }
コード例 #14
0
void* handle_tcp_client(void * arg)
{
	printf("handling tcp client\n");
	
	char *buffer = NULL;
	Header hdr;
	int received = -1;
	long sock = reinterpret_cast<long> (arg);
	/* Receive message */
	do {
	
		if ((received = recv(sock, &hdr, sizeof(Header), 0)) < 0) {
			printf("handle_tcp_client: no header");
			break;
		}
		printf("received = %d\n", received);
		if (received == 0) break;
		while (received < sizeof(Header)) {
			int next_rec;
			if ((next_rec = recv(sock, (char*) &hdr + received, sizeof(Header) - received, 0)) <= 0) {
				break;
			} else {
				usleep(100);
			}

			
			received += next_rec;
			printf("received part = %d\n", next_rec);
		}
		if (received < sizeof(Header)) break;
		for (int i=0; i < received; i++) printf("%02x ", (reinterpret_cast<char*> (&hdr))[i]);
		printf("\n");
		
		hdr.cookie = ntohs(hdr.cookie);
		hdr.id = ntohs(hdr.id);
		hdr.cmd = ntohs(hdr.cmd);
		hdr.len = ntohs(hdr.len);
		hdr.seq = ntohl(hdr.seq);
		
		printf("cookie=%x id=%d cmd=%d len=%d seq=%ld\n", hdr.cookie, hdr.id, hdr.cmd, (hdr.len), (hdr.seq))	;
	
	
		if ((hdr.id == 0 && hdr.cookie == OK_COOKIE) || (hdr.id < MAX_ID && hdr.cookie == session[hdr.id].cookie)) {
			printf("OK\n");
			if (hdr.len > 0) {
				buffer = (char*) malloc(hdr.len);
				if (buffer == NULL) {
					printf("out of memory\n");
					break;
				}
				for (received = 0; received < hdr.len; ) {
					int next_rec = recv(sock, buffer + received, hdr.len - received, 0);
					if (next_rec < 0) {
						printf("couldn't get all buffer\n");
						break;
					}
					received += next_rec;
				}
				if (received < hdr.len) break;
				printf("got payload\n");
			}
			if ((Cmds) hdr.cmd == E_STORE) {
				printf("adding len=%d\n", hdr.len);
				if (AddBuf(hdr.id, hdr.seq, buffer, hdr.len)) {
					free(buffer);
				}
				buffer = NULL;
			} else 
			if ((Cmds) hdr.cmd == E_GET) {
				printf("E_GET\n");
				if (buffer) {
					free(buffer);
					buffer = NULL;
				}
				if (SendBuf(hdr.id, hdr.seq, sock)) break;
			} else 
			if ((Cmds) hdr.cmd == E_STATUS) {
				if (hdr.len != sizeof(BUF_Status)) {
					printf("hdr.len != sizeof(BUF_Status)\n");
				} else {
					printf("E_STATUS\n");
					BUF_Status* status = (BUF_Status*) buffer;
					session[hdr.id].alert = ntohs(status->alert);
					session[hdr.id].last_access = time(NULL);
 				}
				if (buffer != NULL) {
					free(buffer);
					buffer = NULL;
				}
			} else
			if ((Cmds) hdr.cmd == E_CHECK) {
				Response r;
				BUF_R_Check c;
				printf("E_CHECK\n");
				time_t now = time(NULL);
				r.response = htons(E_R_CHECK);
				r.len = htons(sizeof(BUF_R_Check));
				c.alert = htons(session[hdr.id].alert);
				c.last_access_sec = htons((int) difftime(now, session[hdr.id].last_access));
				
				if (send(sock, &r, sizeof(r), 0) != sizeof(r)) break;
				if (send(sock, &c, sizeof(c), 0) != sizeof(c)) break;				
			} else
			if ((Cmds) hdr.cmd == E_CREATE) {
				Response r;
				BUF_R_Create_Login c;
				time_t now = time(NULL);
				printf("E_CREATE\n");
				
				if (hdr.len != sizeof(BUF_Create_Login)) {
					printf("hdr.len != sizeof(BUF_Create_Login)\n");
				} else {
					BUF_Create_Login* status = (BUF_Create_Login*) buffer;
					char username[MAX_NAME_LEN];
					char password[MAX_NAME_LEN];
					strncpy(username, status->username, MAX_NAME_LEN);
					strncpy(password, status->password, MAX_NAME_LEN);
					username[MAX_NAME_LEN-1] = 0;
					password[MAX_NAME_LEN-1] = 0;
					bool done = false;
					for (int i = 0; i < MAX_ID; i++) {
						if (users[i].username[0] == 0 || !strcmp(users[i].username, username) || difftime(now, users[i].last_access) > 60*60*24) {
							strcpy(users[i].password, password);
							users[i].last_access = time(NULL);
							pthread_mutex_lock(&g_mutex);
							while (session[next_id].last_access != 0 && difftime(now, session[next_id].last_access) < 60) {
								next_id = (next_id + 1) & MAX_ID;
								usleep(1000);
								now = time(NULL);
							}
							int id = next_id;
							next_id	= (next_id + 1) % MAX_ID;
							pthread_mutex_unlock(&g_mutex);
							
							pthread_mutex_lock(&session[next_id].mutex);

							for (int i = 0; i < MAX_BUFS; i++) 
								if (session[id].buf[i] != NULL) {
									free(session[id].buf);
									session[id].buf[i] = NULL;
								}
							session[id].alert = 0;
							session[id].head = 0;
							session[id].tail = 0;
							session[id].last_access = time(NULL);
							session[id].cookie = (unsigned short) time(NULL);
							pthread_mutex_unlock(&session[id].mutex);
							Response r;
							BUF_R_Create_Login c;
							r.response = htons(E_R_CREATE);
							r.len = htons(sizeof(BUF_R_Create_Login));
							c.id = htons(id);
							c.cookie = htons(session[id].cookie);
							done = true;
							if (send(sock, &r, sizeof(r), 0) != sizeof(r)) break;
							if (send(sock, &c, sizeof(c), 0) != sizeof(c)) break;				
							break;
							
						}
					}
					if (!done) {
						Response r;
						BUF_R_Create_Login c;
						r.response = htons(E_R_CREATE);
						r.len = htons(sizeof(BUF_R_Create_Login));
						c.id = htons(0xFFFF);
						c.cookie = htons(0xFFFF);
						if (send(sock, &r, sizeof(r), 0) != sizeof(r)) break;
						if (send(sock, &c, sizeof(c), 0) != sizeof(c)) break;				
					}						
				}
			} else
			if ((Cmds) hdr.cmd == E_LOGIN) {
				Response r;
				BUF_R_Create_Login c;
				printf("E_LOGIN");
				if (hdr.len != sizeof(BUF_Create_Login)) {
					printf("hdr.len != sizeof(BUF_Create_Login)\n");
				} else {
					BUF_Create_Login* status = (BUF_Create_Login*) buffer;
					char username[MAX_NAME_LEN];
					char password[MAX_NAME_LEN];
					strncpy(username, status->username, MAX_NAME_LEN);
					strncpy(password, status->password, MAX_NAME_LEN);
					username[MAX_NAME_LEN-1] = 0;
					password[MAX_NAME_LEN-1] = 0;
					printf("username=%s, password=%d\n", username, password);
					bool done = false;
					Response r;
					BUF_R_Create_Login c;
					r.response = htons(E_R_LOGIN);
					r.len = htons(sizeof(BUF_R_Create_Login));
					c.id = htons(0xFFFF);
					c.cookie = htons(0xFFFF);
					
					for (int i = 0; i < MAX_ID; i++) {
						if (!strcmp(users[i].username, username)) {
							if (!strcmp(users[i].password, password)) {
								c.id = htons(users[i].id);
								c.cookie = htons(users[i].cookie);
								printf("found login\n");
								break;
							} else {
								printf("username ok password not=%s\n", users[i].password);
							}

						} else {
							printf("not username=%s\n", users[i].username);
						}

					}
					if (send(sock, &r, sizeof(r), 0) != sizeof(r)) break;
					if (send(sock, &c, sizeof(c), 0) != sizeof(c)) break;				
				}						
			} else {
				printf("Unknown command\n");
				if (buffer) {
					free(buffer);
					buffer = NULL;
				}
			}

				
		}
	
	} while (1);
	close(sock);

	if (buffer != NULL) {
		free(buffer);
		buffer = NULL;
	}
	
	printf("client closed\n");
	pthread_exit( NULL );
}
コード例 #15
0
/// %Realm List command handler
bool AuthSocket::_HandleRealmList()
{
    DEBUG_LOG("Entering _HandleRealmList");
    if (ibuf.GetLength() < 5)
        return false;

    ibuf.Remove(5);

    ///- Get the user id (else close the connection)
    // No SQL injection (escaped user name)

    QueryResult *result = loginDatabase.PQuery("SELECT id,sha_pass_hash FROM account WHERE username = '******'",_safelogin.c_str());
    if(!result)
    {
        sLog.outError("[ERROR] user %s tried to login and we cannot find him in the database.",_login.c_str());
        SetCloseAndDelete();
        return false;
    }

    uint32 id = (*result)[0].GetUInt32();
    std::string rI = (*result)[1].GetCppString();
    delete result;

    ///- Update realm list if need
    m_realmList.UpdateIfNeed();

    ///- Circle through realms in the RealmList and construct the return packet (including # of user characters in each realm)
    ByteBuffer pkt;
    pkt << (uint32) 0;
    pkt << (uint16) m_realmList.size();
    RealmList::RealmMap::const_iterator i;
    for( i = m_realmList.begin(); i != m_realmList.end(); ++i )
    {
        uint8 AmountOfCharacters;

        // No SQL injection. id of realm is controlled by the database.
        result = loginDatabase.PQuery( "SELECT numchars FROM realmcharacters WHERE realmid = '%d' AND acctid='%u'",i->second.m_ID,id);
        if( result )
        {
            Field *fields = result->Fetch();
            AmountOfCharacters = fields[0].GetUInt8();
            delete result;
        }
        else
            AmountOfCharacters = 0;

        uint8 lock = (i->second.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0;

        pkt << i->second.icon;                              // realm type
        pkt << lock;                                        // if 1, then realm locked
        pkt << i->second.color;                             // if 2, then realm is offline
        pkt << i->first;
        pkt << i->second.address;
        pkt << i->second.populationLevel;
        pkt << AmountOfCharacters;
        pkt << i->second.timezone;                          // realm category
        pkt << (uint8) 0x2C;                                // unk, may be realm number/id?
    }
    pkt << (uint8) 0x10;
    pkt << (uint8) 0x00;

    ByteBuffer hdr;
    hdr << (uint8) REALM_LIST;
    hdr << (uint16)pkt.size();
    hdr.append(pkt);

    SendBuf((char const*)hdr.contents(), hdr.size());

    return true;
}
コード例 #16
0
ファイル: AuthSocket.cpp プロジェクト: X-Core/X-core-addons
/// Logon Challenge command handler
bool AuthSocket::_HandleLogonChallenge()
{
    DEBUG_LOG("Entering _HandleLogonChallenge");
    if (ibuf.GetLength() < sizeof(sAuthLogonChallenge_C))
        return false;

    ///- Read the first 4 bytes (header) to get the length of the remaining of the packet
    std::vector<uint8> buf;
    buf.resize(4);

    ibuf.Read((char *)&buf[0], 4);

    EndianConvert(*((uint16*)(buf[0])));
    uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size;
    DEBUG_LOG("[AuthChallenge] got header, body is %#04x bytes", remaining);

    if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (ibuf.GetLength() < remaining))
        return false;

    //No big fear of memory outage (size is int16, i.e. < 65536)
    buf.resize(remaining + buf.size() + 1);
    buf[buf.size() - 1] = 0;
    sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0];

    ///- Read the remaining of the packet
    ibuf.Read((char *)&buf[4], remaining);
    DEBUG_LOG("[AuthChallenge] got full packet, %#04x bytes", ch->size);
    DEBUG_LOG("[AuthChallenge] name(%d): '%s'", ch->I_len, ch->I);

    // BigEndian code, nop in little endian case
    // size already converted
    EndianConvert(*((uint32*)(&ch->gamename[0])));
    EndianConvert(ch->build);
    EndianConvert(*((uint32*)(&ch->platform[0])));
    EndianConvert(*((uint32*)(&ch->os[0])));
    EndianConvert(*((uint32*)(&ch->country[0])));
    EndianConvert(ch->timezone_bias);
    EndianConvert(ch->ip);

    ByteBuffer pkt;

    _login = (const char*)ch->I;
    _build = ch->build;

    ///- Normalize account name
    //utf8ToUpperOnlyLatin(_login); -- client already send account in expected form

    //Escape the user login to avoid further SQL injection
    //Memory will be freed on AuthSocket object destruction
    _safelogin = _login;
    loginDatabase.escape_string(_safelogin);

    pkt << (uint8) AUTH_LOGON_CHALLENGE;
    pkt << (uint8) 0x00;

    ///- Verify that this IP is not in the ip_banned table
    // No SQL injection possible (paste the IP address as passed by the socket)
    std::string address = GetRemoteAddress();
    loginDatabase.escape_string(address);
    QueryResult *result = loginDatabase.PQuery("SELECT unbandate FROM ip_banned WHERE "
    //    permanent                    still banned
        "(unbandate = bandate OR unbandate > UNIX_TIMESTAMP()) AND ip = '%s'", address.c_str());
    if (result)
    {
        pkt << (uint8)WOW_FAIL_BANNED;
        BASIC_LOG("[AuthChallenge] Banned ip %s tries to login!", GetRemoteAddress().c_str());
        delete result;
    }
    else
    {
        ///- Get the account details from the account table
        // No SQL injection (escaped user name)

        result = loginDatabase.PQuery("SELECT sha_pass_hash,id,locked,last_ip,gmlevel,v,s,trial_client FROM account WHERE username = '******'",_safelogin.c_str ());
        if( result )
        {
            ///- If the IP is 'locked', check that the player comes indeed from the correct IP address
            bool locked = false;
            if((*result)[2].GetUInt8() == 1)                // if ip is locked
            {
                DEBUG_LOG("[AuthChallenge] Account '%s' is locked to IP - '%s'", _login.c_str(), (*result)[3].GetString());
                DEBUG_LOG("[AuthChallenge] Player address is '%s'", GetRemoteAddress().c_str());
                if ( strcmp((*result)[3].GetString(),GetRemoteAddress().c_str()) )
                {
                    DEBUG_LOG("[AuthChallenge] Account IP differs");
                    pkt << (uint8) WOW_FAIL_SUSPENDED;
                    locked=true;
                }
                else
                {
                    DEBUG_LOG("[AuthChallenge] Account IP matches");
                }
            }
            else
            {
                DEBUG_LOG("[AuthChallenge] Account '%s' is not locked to ip", _login.c_str());
            }

            if (!locked)
            {
                ///- If the account is banned, reject the logon attempt
                QueryResult *banresult = loginDatabase.PQuery("SELECT bandate,unbandate FROM account_banned WHERE "
                    "id = %u AND active = 1 AND (unbandate > UNIX_TIMESTAMP() OR unbandate = bandate)", (*result)[1].GetUInt32());
                if(banresult)
                {
                    if((*banresult)[0].GetUInt64() != (*banresult)[1].GetUInt64())
                    {
                        pkt << (uint8) WOW_FAIL_BANNED;
                        BASIC_LOG("[AuthChallenge] Banned account %s tries to login!",_login.c_str ());
                    }
                    else
                    {
                        pkt << (uint8) WOW_FAIL_SUSPENDED;
                        BASIC_LOG("[AuthChallenge] Temporarily banned account %s tries to login!",_login.c_str ());
                    }

                    delete banresult;
                }
                else
                {
                    ///- Get the password from the account table, upper it, and make the SRP6 calculation
                    std::string rI = (*result)[0].GetCppString();

                    ///- Don't calculate (v, s) if there are already some in the database
                    std::string databaseV = (*result)[5].GetCppString();
                    std::string databaseS = (*result)[6].GetCppString();

                    DEBUG_LOG("database authentication values: v='%s' s='%s'", databaseV.c_str(), databaseS.c_str());

                    // multiply with 2, bytes are stored as hexstring
                    if(databaseV.size() != s_BYTE_SIZE*2 || databaseS.size() != s_BYTE_SIZE*2)
                        _SetVSFields(rI);
                    else
                    {
                        s.SetHexStr(databaseS.c_str());
                        v.SetHexStr(databaseV.c_str());
                    }

                    b.SetRand(19 * 8);
                    BigNumber gmod = g.ModExp(b, N);
                    B = ((v * 3) + gmod) % N;

                    ASSERT(gmod.GetNumBytes() <= 32);

                    BigNumber unk3;
                    unk3.SetRand(16 * 8);

                    ///- Fill the response packet with the result
                    pkt << uint8(WOW_SUCCESS);

                    // B may be calculated < 32B so we force minimal length to 32B
                    pkt.append(B.AsByteArray(32), 32);      // 32 bytes
                    pkt << uint8(1);
                    pkt.append(g.AsByteArray(), 1);
                    pkt << uint8(32);
                    pkt.append(N.AsByteArray(32), 32);
                    pkt.append(s.AsByteArray(), s.GetNumBytes());// 32 bytes
                    pkt.append(unk3.AsByteArray(16), 16);
                    uint8 securityFlags = 0;
                    pkt << uint8(securityFlags);            // security flags (0x0...0x04)

                    if(securityFlags & 0x01)                // PIN input
                    {
                        pkt << uint32(0);
                        pkt << uint64(0) << uint64(0);      // 16 bytes hash?
                    }

                    if(securityFlags & 0x02)                // Matrix input
                    {
                        pkt << uint8(0);
                        pkt << uint8(0);
                        pkt << uint8(0);
                        pkt << uint8(0);
                        pkt << uint64(0);
                    }

                    if(securityFlags & 0x04)                // Security token input
                    {
                        pkt << uint8(1);
                    }

                    uint8 secLevel = (*result)[4].GetUInt8();
                    _accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR;
                    _isTrial = (*result)[7].GetUInt8() == 1 ? true : false; 

                    _localizationName.resize(4);
                    for(int i = 0; i < 4; ++i)
                        _localizationName[i] = ch->country[4-i-1];

                    BASIC_LOG("[AuthChallenge] account %s is using '%c%c%c%c' locale (%u)", _login.c_str (), ch->country[3], ch->country[2], ch->country[1], ch->country[0], GetLocaleByName(_localizationName));
                }
            }
            delete result;
        }
        else                                                // no account
        {
            pkt<< (uint8) WOW_FAIL_UNKNOWN_ACCOUNT;
        }
    }
    SendBuf((char const*)pkt.contents(), pkt.size());
    return true;
}
コード例 #17
0
BOOL SocksParser::Auth(int s,char* username,char* password,BOOL NeedAuth)
{
	/*
	  +----+----------+----------+
	  |VER | NMETHODS | METHODS  |
	  +----+----------+----------+
	  | 1  |    1     | 1 to 255 |
	  +----+----------+----------+
	*/
	int i = 0;
	char buffer[1024];

	RecvBuf(s,buffer,2);

	int type = buffer[1];

	RecvBuf(s,buffer,type);

	for (i = 0;i < type;++i)
		if (buffer[i] == 0x02)
			break;
	/*
	 +----+-----------------+
	 |VER | METHOD CHOSSED  |
	 +----+-----------------+
	 | 1  |    1 to 255     |
	 +----+-----------------+
	*/
	char replay[2];
	replay[0] = 0x05;

	//需要身份认证
	if (NeedAuth)
	{
		//没有密码
		if (i == type)
		{
			replay[1] = 0xff;
		}
		else
		{
			replay[1] = 0x02;
		}
	}
	//不需要
	else
	{
		replay[1] = 0x00;
	}
	SendBuf(s,replay,2);

	//只支持密码通信
	if (replay[1] == 0xff) 
		return FALSE;

	if (replay[1] == 0x00)
		return TRUE;
	/*
	+----+------+----------+------+----------+
	|VER | ULEN |  UNAME   | PLEN |  PASSWD  |
	+----+------+----------+------+----------+
	| 1  |  1   | 1 to 255 |  1   | 1 to 255 |
	+----+------+----------+------+----------+
	*/
	RecvBuf(s,buffer,2);
	int nLen = buffer[1];

	RecvBuf(s,buffer,nLen);

	buffer[nLen] = 0;
	char user[256];
	strncpy(user,buffer,256);

	RecvBuf(s,buffer,1);
	int nPLen = buffer[0];
	RecvBuf(s,buffer,nPLen);

	buffer[nPLen] = 0;
	char pwd[256];

	strncpy(pwd,buffer,256);
	/*
	+----+--------+
	|VER | STATUS |
	+----+--------+
	| 1  |   1    |
	+----+--------+
	*/
	replay[0] = 0x05;

	if (!strcmp(user,username) && !strcmp(pwd,password))
		replay[1] = 0x00;
	else
		replay[1] = 0x01;

	SendBuf(s,replay,2);
	return replay[1] == 0x00;
}
コード例 #18
0
ファイル: payload7.c プロジェクト: ekapujiw2002/payloadku
void GrabAndSendCameraData(CvCapture* aCamHandle, int i2c_handle, int skippedFrame, int delayPixelSending, unsigned int idPayloadNum, GPS_DATA *last_data, unsigned char rf_buffer_len) {
    unsigned char frameBuff[645*200], buff_gps_data[40];
    unsigned int i, idPixel;

    //capture camera, skip n frame
    IplImage *img = 0;
    uint8_t cntSkipFrame = 0;
    while (cntSkipFrame < skippedFrame) {
        //grab frame
        img = cvQueryFrame(aCamHandle);
        if (img) cntSkipFrame++;
    }

    //get picture and resize it
    //cvSaveImage("/dev/shm/capture.jpg", img, 0);

    //create image to store
    IplImage *dest = cvCreateImage(cvSize(200, 200), img->depth, img->nChannels);

    //resize it
    cvResize(img, dest, CV_INTER_LANCZOS4);

    //save the resized image
    //~ cvSaveImage("resized.jpg", dest, 0);

    //view pixel info 
    int hcnt, wcnt;

    //method 1:
    //print header paket gambar
    snprintf((char*) frameBuff, 10, "\r%.3d\xff\r", idPayloadNum);
    SendBuf(COM_PORT, frameBuff, 7);
    usleep(RF_DELAY_LESS_PACKET_US);
    
    //print pixel
    idPixel = 0;
    for (hcnt = 0; hcnt < dest->height; hcnt++) { //loop height
        unsigned char* row = &CV_IMAGE_ELEM(dest, unsigned char, hcnt, 0); //row scanline

        //print header frame
        //~ uchar dataTX[4] = {0xff}; //header data
        //~ dataTX[1] = ((hcnt + 1) / 100) + 0x30; //counter height
        //~ dataTX[2] = (((hcnt + 1) % 100) / 10) + 0x30;
        //~ dataTX[3] = ((hcnt + 1) % 10) + 0x30;        
        
        frameBuff[idPixel++] = 0xff;
        frameBuff[idPixel++] = ((hcnt + 1) / 100) + 0x30; //counter height
        frameBuff[idPixel++] = (((hcnt + 1) % 100) / 10) + 0x30;
        frameBuff[idPixel++] = ((hcnt + 1) % 10) + 0x30;

#if VERBOSE==1
        printf("Processing frame #%d\r\n", hcnt + 1);
#endif        

        //send header
        //~ SendBuf(COM_PORT, dataTX, 4);
        //~ usleep(RF_DELAY_LESS_PACKET_US);

        //loop per width
        for (wcnt = 0; wcnt < dest->width * dest->nChannels; wcnt += dest->nChannels) {
			// opencv rgb data sequence = BGR
            //            row[x] = {R,G,B};
			//~ frameBuff[wcnt + 4] = (row[wcnt + 2] == 0xff) ? 0xfe : row[wcnt + 2];
            //~ frameBuff[wcnt + 1 + 4] = (row[wcnt + 1] == 0xff) ? 0xfe : row[wcnt + 1];
            //~ frameBuff[wcnt + 2 + 4] = (row[wcnt + 0] == 0xff) ? 0xfe : row[wcnt + 0];
            frameBuff[idPixel++] = (row[wcnt + 2] == 0xff) ? 0xfe : row[wcnt + 2];
            frameBuff[idPixel++] = (row[wcnt + 1] == 0xff) ? 0xfe : row[wcnt + 1];
            frameBuff[idPixel++] = (row[wcnt + 0] == 0xff) ? 0xfe : row[wcnt + 0];
			
            //~ SendByte(COM_PORT, (row[wcnt + 2] == 0xff) ? 0xfe : row[wcnt + 2]);
            //usleep(5);
            //~ SendByte(COM_PORT, (row[wcnt + 1] == 0xff) ? 0xfe : row[wcnt + 1]);
            //usleep(5);
            //~ SendByte(COM_PORT, (row[wcnt + 0] == 0xff) ? 0xfe : row[wcnt + 0]);
            //usleep(5);
            
            //delay for buffer radio
            //~ if(wcnt%32==0)
				//~ usleep(delayPixelSending);
        }

        //send frame package
        //SendBuf(COM_PORT, frameBuff, 600);

        //delay for transceiver
        //usleep(delayPixelSending);
        
        //get gps data
		//~ GetAndFormatGPSData(i2c_handle, buff_gps_data, last_data);
		GetAndFormatGPSData(i2c_handle, &frameBuff[idPixel], last_data);
	
		//send the gps data
		//~ SendBuf(COM_PORT, buff_gps_data, 18); 
		//~ usleep(2000);
		//~ SendBuf(COM_PORT, &buff_gps_data[18], 19); 
		//~ usleep(RF_DELAY_US);
		
		//delay buffer radio
		//~ usleep(delayPixelSending+2000);
		
		//tail
		//~ snprintf(buff_gps_data, 5, " INA");
		idPixel += 37;
		snprintf(&frameBuff[idPixel], 6, " %s", "GPS");
		idPixel += 4;
		
		//send the data
		//~ SendBuf(COM_PORT, buff_gps_data, 4); 
		
		//~ for(i=0;i<672;i+=32)
		//~ {
			//~ SendBuf(COM_PORT, &frameBuff[i], 32); 
			//~ usleep(RF_DELAY_HALF_DUPLEX_US);
		//~ }
		
		//~ for(i=0;i<672;i++)
		//~ {
			//~ SendByte(COM_PORT, frameBuff[i]); 
			//~ if(i%32==0)
				//~ usleep(RF_DELAY_HALF_DUPLEX_US);
		//~ }
		//~ usleep(50000);
		
		//~ printf("F#%.3d = %.3d\r\n", hcnt, idPixel);
		
		//~ if(hcnt==0) break;
    }
    
    //save to file
    //~ FILE *fp;
	//~ fp=fopen("raw_cam.log", "wb+");
	//~ fwrite(
		//~ frameBuff, 
		//~ sizeof(frameBuff[0]), 
		//~ /* sizeof(frameBuff)/sizeof(frameBuff[0]) */
		//~ idPixel, 
		//~ fp);
	//~ fclose(fp);
    
    //send all data
    printf("Going to send %ld byte with delay %d us\r\n", idPixel, delayPixelSending);  

	//trw433
	#ifdef RADIO_TYPE_TRW433
		for(i=0;i<(idPixel);i++)
		{
			SendByte(COM_PORT, frameBuff[i]); 
			if(i%(rf_buffer_len-1)==0)
				//~ usleep(RF_DELAY_HALF_DUPLEX_US);
				usleep(delayPixelSending);
		}
		
		usleep(RF_DELAY_LESS_PACKET_US);
	#endif
	
	//hm trp
	#ifdef RADIO_TYPE_HMTRP
		for(i=0;i<(idPixel);i++)
		{
			SendByte(COM_PORT, frameBuff[i]); 
			if(i%(32-1)==0)
				//~ usleep(RF_DELAY_HALF_DUPLEX_US);
				usleep(delayPixelSending);
		}
		
		usleep(RF_DELAY_LESS_PACKET_US);
	#endif
}
コード例 #19
0
ファイル: HttpPostSocket.cpp プロジェクト: vata/prebcwow
void HttpPostSocket::DoMultipartPost()
{
	long length = 0; // calculate content_length of our post body
	std::string tmp;

	// fields
	{
		for (std::map<std::string,std::list<std::string> >::iterator it = m_fields.begin(); it != m_fields.end(); it++)
		{
			std::string name = (*it).first;
			std::list<std::string>& ref = (*it).second;
			tmp = "--" + m_boundary + "\r\n"
				"content-disposition: form-data; name=\"" + name + "\"\r\n"
				"\r\n";
			for (std::list<std::string>::iterator it = ref.begin(); it != ref.end(); it++)
			{
				std::string value = *it;
				tmp += value + "\r\n";
			}
			length += (long)tmp.size();
		}
	}

	// files
	{
		for (std::map<std::string,std::string>::iterator it = m_files.begin(); it != m_files.end(); it++)
		{
			std::string name = (*it).first;
			std::string filename = (*it).second;
			long content_length = m_content_length[filename];
			std::string content_type = m_content_type[filename];
			tmp = "--" + m_boundary + "\r\n"
				"content-disposition: form-data; name=\"" + name + "\"; filename=\"" + filename + "\"\r\n"
				"content-type: " + content_type + "\r\n"
				"\r\n";
			length += (long)tmp.size();
			length += content_length;
			length += 2; // crlf after file
		}
	}

	// end
	tmp = "--" + m_boundary + "--\r\n";
	length += (long)tmp.size();

	// build header, send body
	SetMethod("POST");
	SetHttpVersion( "HTTP/1.1" );
	AddResponseHeader( "Host", m_host ); // oops - this is actually a request header that we're adding..
	AddResponseHeader( "User-agent", MyUseragent());
	AddResponseHeader( "Accept", "text/html, text/plain, */*;q=0.01" );
	AddResponseHeader( "Connection", "close" );
	AddResponseHeader( "Content-type", "multipart/form-data; boundary=" + m_boundary );
	AddResponseHeader( "Content-length", Utility::l2string(length) );

	SendRequest();

	// send fields
	{
		for (std::map<std::string,std::list<std::string> >::iterator it = m_fields.begin(); it != m_fields.end(); it++)
		{
			std::string name = (*it).first;
			std::list<std::string>& ref = (*it).second;
			tmp = "--" + m_boundary + "\r\n"
				"content-disposition: form-data; name=\"" + name + "\"\r\n"
				"\r\n";
			for (std::list<std::string>::iterator it = ref.begin(); it != ref.end(); it++)
			{
				std::string value = *it;
				tmp += value + "\r\n";
			}
			Send( tmp );
		}
	}

	// send files
	{
		for (std::map<std::string,std::string>::iterator it = m_files.begin(); it != m_files.end(); it++)
		{
			std::string name = (*it).first;
			std::string filename = (*it).second;
			std::string content_type = m_content_type[filename];
			tmp = "--" + m_boundary + "\r\n"
				"content-disposition: form-data; name=\"" + name + "\"; filename=\"" + filename + "\"\r\n"
				"content-type: " + content_type + "\r\n"
				"\r\n";
			Send( tmp );
			{
				FILE *fil = fopen(filename.c_str(),"rb");
				if (fil)
				{
					char slask[2000];
					size_t n;
					while ((n = fread(slask, 1, 2000, fil)) > 0)
					{
						SendBuf(slask, n);
					}
					fclose(fil);
				}
			}
			Send("\r\n");
		}
	}

	// end of send
	Send("--" + m_boundary + "--\r\n");
}