コード例 #1
0
ファイル: stunbuilder.cpp プロジェクト: chenbk85/stunserver
HRESULT CStunMessageBuilder::AddRandomTransactionId(StunTransactionId* pTransId)
{
    StunTransactionId transid;
    uint32_t stun_cookie_nbo = htonl(STUN_COOKIE);

    uint32_t entropy=0;


    // on x86, the rdtsc instruction is about as good as it gets for a random sequence number
    // on linux, there's /dev/urandom


#ifdef _WIN32
    // on windows, there's lots of simple stuff we can get at to give us a random number
    // the rdtsc instruction is about as good as it gets
    uint64_t clock = __rdtsc();
    entropy ^= (uint32_t)(clock);
#else
    // on linux, /dev/urandom should be sufficient
    {
        int randomfile = ::open("/dev/urandom", O_RDONLY);
        if (randomfile >= 0)
        {
            int readret = read(randomfile, &entropy, sizeof(entropy));
            UNREFERENCED_VARIABLE(readret);
            ASSERT(readret > 0);
            close(randomfile);
        }
    }


    if (entropy == 0)
    {
        entropy ^= getpid();
        entropy ^= reinterpret_cast<uintptr_t>(this);
        entropy ^= time(NULL);
        entropy ^= AtomicIncrement(&g_sequence_number);
    }

#endif


    srand(entropy);


    // the first four bytes of the transaction id is always the magic cookie
    // followed by 12 bytes of the real transaction id
    memcpy(transid.id, &stun_cookie_nbo, sizeof(stun_cookie_nbo));
    for (int x = 4; x < (STUN_TRANSACTION_ID_LENGTH-4); x++)
    {
        transid.id[x] = (uint8_t)(rand() % 256);
    }

    if (pTransId)
    {
        *pTransId = transid;
    }

    return AddTransactionId(transid);
}
コード例 #2
0
ファイル: stunbuilder.cpp プロジェクト: chenbk85/stunserver
HRESULT CStunMessageBuilder::AddMessageIntegrityLongTerm(const char* pszUserName, const char* pszRealm, const char* pszPassword)
{
    HRESULT hr = S_OK;
    const size_t MAX_KEY_SIZE = MAX_STUN_AUTH_STRING_SIZE*3 + 2;
    uint8_t key[MAX_KEY_SIZE + 1]; // long enough for 64-char strings and two semicolons and a null char for debugging

    uint8_t hash[MD5_DIGEST_LENGTH] = {};
    uint8_t* pResult = NULL;
    uint8_t* pDst = key;

    size_t lenUserName = pszUserName ? strlen(pszUserName) : 0;
    size_t lenRealm = pszRealm ? strlen(pszRealm) : 0;
    size_t lenPassword = pszPassword ? strlen(pszPassword) : 0;
    size_t lenTotal = lenUserName + lenRealm + lenPassword + 2; // +2 for the two colons

    UNREFERENCED_VARIABLE(pResult);

    ChkIfA(lenTotal > MAX_KEY_SIZE, E_INVALIDARG); // if we ever hit this limit, just increase MAX_STUN_AUTH_STRING_SIZE

    // too bad CDatastream really only works on refcounted buffers.  Otherwise, we wouldn't have to do all this messed up pointer math

    // We could create a refcounted buffer in this function, but that would mean a call to "new and delete", and we're trying to avoid memory allocations in
    // critical code paths because they are a proven perf hit

    // TODO - Fix CDataStream and CBuffer so that "ref counted buffers" are no longer needed

    pDst = key;

    memcpy(pDst, pszUserName, lenUserName);
    pDst += lenUserName;

    *pDst = ':';
    pDst++;

    memcpy(pDst, pszRealm, lenRealm);
    pDst += lenRealm;

    *pDst = ':';
    pDst++;

    memcpy(pDst, pszPassword, lenPassword);
    pDst += lenPassword;
    *pDst ='\0'; // null terminate for debugging (this char doesn not get hashed

    ASSERT((pDst-key) == lenTotal);

#ifndef __APPLE__
    pResult = MD5(key, lenTotal, hash);
#else
    pResult = CC_MD5(key, lenTotal, hash);
#endif

    ASSERT(pResult != NULL);
    hr= AddMessageIntegrityImpl(hash, MD5_DIGEST_LENGTH);

Cleanup:
    return hr;
}
コード例 #3
0
ファイル: stunbuilder.cpp プロジェクト: chenbk85/stunserver
HRESULT CStunMessageBuilder::AddMessageIntegrityImpl(uint8_t* key, size_t keysize)
{
    HRESULT hr = S_OK;
    const size_t c_hmacsize = 20;
    uint8_t hmacvaluedummy[c_hmacsize] = {}; // zero-init
    unsigned int resultlength = c_hmacsize;
    uint8_t* pDstBuf = NULL;

    CRefCountedBuffer spBuffer;
    void* pData = NULL;
    size_t length = 0;
    unsigned char* pHashResult = NULL;
    UNREFERENCED_VARIABLE(pHashResult);

    ChkIfA(key==NULL || keysize <= 0, E_INVALIDARG);

    // add in a "zero-init" HMAC value.  This adds 24 bytes to the length
    Chk(AddAttribute(STUN_ATTRIBUTE_MESSAGEINTEGRITY, hmacvaluedummy, ARRAYSIZE(hmacvaluedummy)));

    Chk(FixLengthField());
    // now do a SHA1 on everything but the last 24 bytes (4 bytes of the attribute header and 20 bytes for the dummy content)

    ChkA(_stream.GetBuffer(&spBuffer));
    pData = spBuffer->GetData();
    length = spBuffer->GetSize();

    ASSERT(length > 24);
    length = length-24;


    // now do a little pointer math so that HMAC can write exactly to where the hash bytes will appear
    pDstBuf = ((uint8_t*)pData) + length + 4;

#ifndef __APPLE__
    pHashResult = HMAC(EVP_sha1(), key, keysize, (uint8_t*)pData, length, pDstBuf, &resultlength);
    ASSERT(resultlength == 20);
    ASSERT(pHashResult != NULL);
#else
    CCHmac(kCCHmacAlgSHA1, key, keysize,(uint8_t*)pData, length, pDstBuf);
    UNREFERENCED_VARIABLE(resultlength);
#endif

Cleanup:
    return hr;
}
コード例 #4
0
void CTestMessageHandler::ToAddr(const char* pszIP, uint16_t port, CSocketAddress* pAddr)
{
    sockaddr_in addr={};
    int result;

    UNREFERENCED_VARIABLE(result);
    
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    
    result = ::inet_pton(AF_INET, pszIP, &addr.sin_addr);
    
    ASSERT(result == 1);
    
    *pAddr = addr;
}
コード例 #5
0
// ----------------------------------------------------------------------------------------------
// this function must *always* return a valid Resource, even for 'missing' resources.
Resource* ResourceManager::LoadAsync(const WCHAR* filename, Resource* def)
{
    AutoSync sync(&m_criticalSection); // CRITICAL SECTION  - ENTIRE FUNCTION
    Resource * res = NULL;
    // check cache, use if already there.
    if(NULL == res)
    {
        auto it = m_loaded.find(filename);
        if(it != m_loaded.end() ) res = it->second;
    }

    // check pending, use if already there.
    if(NULL == res)
    {
        auto it = m_pending.find(filename);
        if(it != m_pending.end() ) res = it->second;
    }

    // create new info and add it to pending list to be loaded.
    if(NULL == res)
    {
        ResourceFactory * factory = GetFactory(filename);
        if (!factory)
        {
            return NULL;
        }

        res = factory->CreateResource(def);
        m_pending[filename] = res;
        BOOL success = SetEvent(m_EventHandle);
        #ifdef  NDEBUG
        UNREFERENCED_VARIABLE(success);
        #endif
        assert(success);
    }
    assert(res);
    res->AddRef();
    return res;
}
コード例 #6
0
// ----------------------------------------------------------------------------------------------
Resource* ColladaModelFactory::CreateResource(Resource* def)
{
    UNREFERENCED_VARIABLE(def);
    return new Model();
}