Such style. (Code style unification)

This commit is contained in:
Thulinma 2014-06-18 10:39:27 +02:00
parent 57bcd8f25c
commit 8c01ec8897
57 changed files with 6548 additions and 6437 deletions

View file

@ -39,59 +39,61 @@ std::map<unsigned int, RTMPStream::Chunk> RTMPStream::lastrecv;
#include <openssl/hmac.h>
#define P1024 \
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF"
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DD" \
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF"
uint8_t genuineFMSKey[] = {0x47, 0x65, 0x6e, 0x75, 0x69, 0x6e, 0x65, 0x20, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x46, 0x6c, 0x61, 0x73, 0x68, 0x20,
0x4d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x53, 0x65, 0x72,
0x76, // Genuine Adobe Flash Media Server 001
0x65, 0x72, 0x20, 0x30, 0x30, 0x31, 0xf0, 0xee, 0xc2, 0x4a, 0x80, 0x68, 0xbe, 0xe8, 0x2e, 0x00, 0xd0, 0xd1, 0x02, 0x9e, 0x7e, 0x57, 0x6e, 0xec,
0x5d, 0x2d, 0x29, 0x80, 0x6f, 0xab, 0x93, 0xb8, 0xe6, 0x36, 0xcf, 0xeb, 0x31, 0xae}; // 68
0x4d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x53, 0x65, 0x72,
0x76, // Genuine Adobe Flash Media Server 001
0x65, 0x72, 0x20, 0x30, 0x30, 0x31, 0xf0, 0xee, 0xc2, 0x4a, 0x80, 0x68, 0xbe, 0xe8, 0x2e, 0x00, 0xd0, 0xd1, 0x02, 0x9e, 0x7e, 0x57, 0x6e, 0xec,
0x5d, 0x2d, 0x29, 0x80, 0x6f, 0xab, 0x93, 0xb8, 0xe6, 0x36, 0xcf, 0xeb, 0x31, 0xae
}; // 68
uint8_t genuineFPKey[] = {0x47, 0x65, 0x6e, 0x75, 0x69, 0x6e, 0x65, 0x20, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20, 0x46, 0x6c, 0x61, 0x73, 0x68, 0x20,
0x50, 0x6c, 0x61,
0x79, // Genuine Adobe Flash Player 001
0x65, 0x72, 0x20, 0x30, 0x30, 0x31, 0xf0, 0xee, 0xc2, 0x4a, 0x80, 0x68, 0xbe, 0xe8, 0x2e, 0x00, 0xd0, 0xd1, 0x02, 0x9e, 0x7e, 0x57, 0x6e, 0xec,
0x5d, 0x2d, 0x29, 0x80, 0x6f, 0xab, 0x93, 0xb8, 0xe6, 0x36, 0xcf, 0xeb, 0x31, 0xae}; // 62
0x50, 0x6c, 0x61,
0x79, // Genuine Adobe Flash Player 001
0x65, 0x72, 0x20, 0x30, 0x30, 0x31, 0xf0, 0xee, 0xc2, 0x4a, 0x80, 0x68, 0xbe, 0xe8, 0x2e, 0x00, 0xd0, 0xd1, 0x02, 0x9e, 0x7e, 0x57, 0x6e, 0xec,
0x5d, 0x2d, 0x29, 0x80, 0x6f, 0xab, 0x93, 0xb8, 0xe6, 0x36, 0xcf, 0xeb, 0x31, 0xae
}; // 62
inline uint32_t GetDigestOffset(uint8_t *pBuffer, uint8_t scheme){
if (scheme == 0){
inline uint32_t GetDigestOffset(uint8_t * pBuffer, uint8_t scheme) {
if (scheme == 0) {
return ((pBuffer[8] + pBuffer[9] + pBuffer[10] + pBuffer[11]) % 728) + 12;
}else{
} else {
return ((pBuffer[772] + pBuffer[773] + pBuffer[774] + pBuffer[775]) % 728) + 776;
}
}
inline uint32_t GetDHOffset(uint8_t *pBuffer, uint8_t scheme){
if (scheme == 0){
inline uint32_t GetDHOffset(uint8_t * pBuffer, uint8_t scheme) {
if (scheme == 0) {
return ((pBuffer[1532] + pBuffer[1533] + pBuffer[1534] + pBuffer[1535]) % 632) + 772;
}else{
} else {
return ((pBuffer[768] + pBuffer[769] + pBuffer[770] + pBuffer[771]) % 632) + 8;
}
}
class DHWrapper{
class DHWrapper {
private:
int32_t _bitsCount;
DH *_pDH;
uint8_t *_pSharedKey;
DH * _pDH;
uint8_t * _pSharedKey;
int32_t _sharedKeyLength;
BIGNUM *_peerPublickey;
BIGNUM * _peerPublickey;
public:
DHWrapper(int32_t bitsCount);
virtual ~DHWrapper();
bool Initialize();
bool CopyPublicKey(uint8_t *pDst, int32_t dstLength);
bool CopyPrivateKey(uint8_t *pDst, int32_t dstLength);
bool CreateSharedKey(uint8_t *pPeerPublicKey, int32_t length);
bool CopySharedKey(uint8_t *pDst, int32_t dstLength);
bool CopyPublicKey(uint8_t * pDst, int32_t dstLength);
bool CopyPrivateKey(uint8_t * pDst, int32_t dstLength);
bool CreateSharedKey(uint8_t * pPeerPublicKey, int32_t length);
bool CopySharedKey(uint8_t * pDst, int32_t dstLength);
private:
void Cleanup();
bool CopyKey(BIGNUM *pNum, uint8_t *pDst, int32_t dstLength);
bool CopyKey(BIGNUM * pNum, uint8_t * pDst, int32_t dstLength);
};
DHWrapper::DHWrapper(int32_t bitsCount){
DHWrapper::DHWrapper(int32_t bitsCount) {
_bitsCount = bitsCount;
_pDH = 0;
_pSharedKey = 0;
@ -99,73 +101,73 @@ DHWrapper::DHWrapper(int32_t bitsCount){
_peerPublickey = 0;
}
DHWrapper::~DHWrapper(){
DHWrapper::~DHWrapper() {
Cleanup();
}
bool DHWrapper::Initialize(){
bool DHWrapper::Initialize() {
Cleanup();
_pDH = DH_new();
if ( !_pDH){
if (!_pDH) {
Cleanup();
return false;
}
_pDH->p = BN_new();
if ( !_pDH->p){
if (!_pDH->p) {
Cleanup();
return false;
}
_pDH->g = BN_new();
if ( !_pDH->g){
if (!_pDH->g) {
Cleanup();
return false;
}
if (BN_hex2bn( &_pDH->p, P1024) == 0){
if (BN_hex2bn(&_pDH->p, P1024) == 0) {
Cleanup();
return false;
}
if (BN_set_word(_pDH->g, 2) != 1){
if (BN_set_word(_pDH->g, 2) != 1) {
Cleanup();
return false;
}
_pDH->length = _bitsCount;
if (DH_generate_key(_pDH) != 1){
if (DH_generate_key(_pDH) != 1) {
Cleanup();
return false;
}
return true;
}
bool DHWrapper::CopyPublicKey(uint8_t *pDst, int32_t dstLength){
if ( !_pDH){
bool DHWrapper::CopyPublicKey(uint8_t * pDst, int32_t dstLength) {
if (!_pDH) {
return false;
}
return CopyKey(_pDH->pub_key, pDst, dstLength);
}
bool DHWrapper::CopyPrivateKey(uint8_t *pDst, int32_t dstLength){
if ( !_pDH){
bool DHWrapper::CopyPrivateKey(uint8_t * pDst, int32_t dstLength) {
if (!_pDH) {
return false;
}
return CopyKey(_pDH->priv_key, pDst, dstLength);
}
bool DHWrapper::CreateSharedKey(uint8_t *pPeerPublicKey, int32_t length){
if ( !_pDH){
bool DHWrapper::CreateSharedKey(uint8_t * pPeerPublicKey, int32_t length) {
if (!_pDH) {
return false;
}
if (_sharedKeyLength != 0 || _pSharedKey){
if (_sharedKeyLength != 0 || _pSharedKey) {
return false;
}
_sharedKeyLength = DH_size(_pDH);
if (_sharedKeyLength <= 0 || _sharedKeyLength > 1024){
if (_sharedKeyLength <= 0 || _sharedKeyLength > 1024) {
return false;
}
_pSharedKey = new uint8_t[_sharedKeyLength];
_peerPublickey = BN_bin2bn(pPeerPublicKey, length, 0);
if ( !_peerPublickey){
if (!_peerPublickey) {
return false;
}
@ -173,93 +175,93 @@ bool DHWrapper::CreateSharedKey(uint8_t *pPeerPublicKey, int32_t length){
return true;
}
bool DHWrapper::CopySharedKey(uint8_t *pDst, int32_t dstLength){
if ( !_pDH){
bool DHWrapper::CopySharedKey(uint8_t * pDst, int32_t dstLength) {
if (!_pDH) {
return false;
}
if (dstLength != _sharedKeyLength){
if (dstLength != _sharedKeyLength) {
return false;
}
memcpy(pDst, _pSharedKey, _sharedKeyLength);
return true;
}
void DHWrapper::Cleanup(){
if (_pDH){
if (_pDH->p){
void DHWrapper::Cleanup() {
if (_pDH) {
if (_pDH->p) {
BN_free(_pDH->p);
_pDH->p = 0;
}
if (_pDH->g){
if (_pDH->g) {
BN_free(_pDH->g);
_pDH->g = 0;
}
DH_free(_pDH);
_pDH = 0;
}
if (_pSharedKey){
if (_pSharedKey) {
delete[] _pSharedKey;
_pSharedKey = 0;
}
_sharedKeyLength = 0;
if (_peerPublickey){
if (_peerPublickey) {
BN_free(_peerPublickey);
_peerPublickey = 0;
}
}
bool DHWrapper::CopyKey(BIGNUM *pNum, uint8_t *pDst, int32_t dstLength){
bool DHWrapper::CopyKey(BIGNUM * pNum, uint8_t * pDst, int32_t dstLength) {
int32_t keySize = BN_num_bytes(pNum);
if ((keySize <= 0) || (dstLength <= 0) || (keySize > dstLength)){
if ((keySize <= 0) || (dstLength <= 0) || (keySize > dstLength)) {
return false;
}
if (BN_bn2bin(pNum, pDst) != keySize){
if (BN_bn2bin(pNum, pDst) != keySize) {
return false;
}
return true;
}
void InitRC4Encryption(uint8_t *secretKey, uint8_t *pubKeyIn, uint8_t *pubKeyOut, RC4_KEY *rc4keyIn, RC4_KEY *rc4keyOut){
void InitRC4Encryption(uint8_t * secretKey, uint8_t * pubKeyIn, uint8_t * pubKeyOut, RC4_KEY * rc4keyIn, RC4_KEY * rc4keyOut) {
uint8_t digest[SHA256_DIGEST_LENGTH];
unsigned int digestLen = 0;
HMAC_CTX ctx;
HMAC_CTX_init( &ctx);
HMAC_Init_ex( &ctx, secretKey, 128, EVP_sha256(), 0);
HMAC_Update( &ctx, pubKeyIn, 128);
HMAC_Final( &ctx, digest, &digestLen);
HMAC_CTX_cleanup( &ctx);
HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx, secretKey, 128, EVP_sha256(), 0);
HMAC_Update(&ctx, pubKeyIn, 128);
HMAC_Final(&ctx, digest, &digestLen);
HMAC_CTX_cleanup(&ctx);
RC4_set_key(rc4keyOut, 16, digest);
HMAC_CTX_init( &ctx);
HMAC_Init_ex( &ctx, secretKey, 128, EVP_sha256(), 0);
HMAC_Update( &ctx, pubKeyOut, 128);
HMAC_Final( &ctx, digest, &digestLen);
HMAC_CTX_cleanup( &ctx);
HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx, secretKey, 128, EVP_sha256(), 0);
HMAC_Update(&ctx, pubKeyOut, 128);
HMAC_Final(&ctx, digest, &digestLen);
HMAC_CTX_cleanup(&ctx);
RC4_set_key(rc4keyIn, 16, digest);
}
void HMACsha256(const void *pData, uint32_t dataLength, const void *pKey, uint32_t keyLength, void *pResult){
void HMACsha256(const void * pData, uint32_t dataLength, const void * pKey, uint32_t keyLength, void * pResult) {
unsigned int digestLen;
HMAC_CTX ctx;
HMAC_CTX_init( &ctx);
HMAC_Init_ex( &ctx, (unsigned char*)pKey, keyLength, EVP_sha256(), 0);
HMAC_Update( &ctx, (unsigned char *)pData, dataLength);
HMAC_Final( &ctx, (unsigned char *)pResult, &digestLen);
HMAC_CTX_cleanup( &ctx);
HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx, (unsigned char *)pKey, keyLength, EVP_sha256(), 0);
HMAC_Update(&ctx, (unsigned char *)pData, dataLength);
HMAC_Final(&ctx, (unsigned char *)pResult, &digestLen);
HMAC_CTX_cleanup(&ctx);
}
bool ValidateClientScheme(uint8_t * pBuffer, uint8_t scheme){
bool ValidateClientScheme(uint8_t * pBuffer, uint8_t scheme) {
uint32_t clientDigestOffset = GetDigestOffset(pBuffer, scheme);
uint8_t *pTempBuffer = new uint8_t[1536 - 32];
uint8_t * pTempBuffer = new uint8_t[1536 - 32];
memcpy(pTempBuffer, pBuffer, clientDigestOffset);
memcpy(pTempBuffer + clientDigestOffset, pBuffer + clientDigestOffset + 32, 1536 - clientDigestOffset - 32);
uint8_t *pTempHash = new uint8_t[512];
uint8_t * pTempHash = new uint8_t[512];
HMACsha256(pTempBuffer, 1536 - 32, genuineFPKey, 30, pTempHash);
bool result = (memcmp(pBuffer + clientDigestOffset, pTempHash, 32) == 0);
DEBUG_MSG(DLVL_MEDIUM, "Client scheme validation %hhi %s", scheme, result?"success":"failed");
DEBUG_MSG(DLVL_MEDIUM, "Client scheme validation %hhi %s", scheme, result ? "success" : "failed");
delete[] pTempBuffer;
delete[] pTempHash;
return result;
@ -268,58 +270,58 @@ bool ValidateClientScheme(uint8_t * pBuffer, uint8_t scheme){
/// Packs up the chunk for sending over the network.
/// \warning Do not call if you are not actually sending the resulting data!
/// \returns A std::string ready to be sent.
std::string & RTMPStream::Chunk::Pack(){
std::string & RTMPStream::Chunk::Pack() {
static std::string output;
output.clear();
bool allow_short = lastsend.count(cs_id);
RTMPStream::Chunk prev = lastsend[cs_id];
unsigned int tmpi;
unsigned char chtype = 0x00;
if (allow_short && (prev.cs_id == cs_id)){
if (msg_stream_id == prev.msg_stream_id){
if (allow_short && (prev.cs_id == cs_id)) {
if (msg_stream_id == prev.msg_stream_id) {
chtype = 0x40; //do not send msg_stream_id
if (len == prev.len){
if (msg_type_id == prev.msg_type_id){
if (len == prev.len) {
if (msg_type_id == prev.msg_type_id) {
chtype = 0x80; //do not send len and msg_type_id
if (timestamp == prev.timestamp){
if (timestamp == prev.timestamp) {
chtype = 0xC0; //do not send timestamp
}
}
}
}
//override - we always sent type 0x00 if the timestamp has decreased since last chunk in this channel
if (timestamp < prev.timestamp){
if (timestamp < prev.timestamp) {
chtype = 0x00;
}
}
if (cs_id <= 63){
if (cs_id <= 63) {
output += (unsigned char)(chtype | cs_id);
}else{
if (cs_id <= 255 + 64){
} else {
if (cs_id <= 255 + 64) {
output += (unsigned char)(chtype | 0);
output += (unsigned char)(cs_id - 64);
}else{
} else {
output += (unsigned char)(chtype | 1);
output += (unsigned char)((cs_id - 64) % 256);
output += (unsigned char)((cs_id - 64) / 256);
}
}
unsigned int ntime = 0;
if (chtype != 0xC0){
if (chtype != 0xC0) {
//timestamp or timestamp diff
if (chtype == 0x00){
if (chtype == 0x00) {
tmpi = timestamp;
}else{
} else {
tmpi = timestamp - prev.timestamp;
}
if (tmpi >= 0x00ffffff){
if (tmpi >= 0x00ffffff) {
ntime = tmpi;
tmpi = 0x00ffffff;
}
output += (unsigned char)((tmpi >> 16) & 0xff);
output += (unsigned char)((tmpi >> 8) & 0xff);
output += (unsigned char)(tmpi & 0xff);
if (chtype != 0x80){
if (chtype != 0x80) {
//len
tmpi = len;
output += (unsigned char)((tmpi >> 16) & 0xff);
@ -327,7 +329,7 @@ std::string & RTMPStream::Chunk::Pack(){
output += (unsigned char)(tmpi & 0xff);
//msg type id
output += (unsigned char)msg_type_id;
if (chtype != 0x40){
if (chtype != 0x40) {
//msg stream id
output += (unsigned char)(msg_stream_id % 256);
output += (unsigned char)(msg_stream_id / 256);
@ -337,28 +339,28 @@ std::string & RTMPStream::Chunk::Pack(){
}
}
//support for 0x00ffffff timestamps
if (ntime){
if (ntime) {
output += (unsigned char)(ntime & 0xff);
output += (unsigned char)((ntime >> 8) & 0xff);
output += (unsigned char)((ntime >> 16) & 0xff);
output += (unsigned char)((ntime >> 24) & 0xff);
}
len_left = 0;
while (len_left < len){
while (len_left < len) {
tmpi = len - len_left;
if (tmpi > RTMPStream::chunk_snd_max){
if (tmpi > RTMPStream::chunk_snd_max) {
tmpi = RTMPStream::chunk_snd_max;
}
output.append(data, len_left, tmpi);
len_left += tmpi;
if (len_left < len){
if (cs_id <= 63){
if (len_left < len) {
if (cs_id <= 63) {
output += (unsigned char)(0xC0 + cs_id);
}else{
if (cs_id <= 255 + 64){
} else {
if (cs_id <= 255 + 64) {
output += (unsigned char)(0xC0);
output += (unsigned char)(cs_id - 64);
}else{
} else {
output += (unsigned char)(0xC1);
output += (unsigned char)((cs_id - 64) % 256);
output += (unsigned char)((cs_id - 64) / 256);
@ -372,7 +374,7 @@ std::string & RTMPStream::Chunk::Pack(){
} //SendChunk
/// Default constructor, creates an empty chunk with all values initialized to zero.
RTMPStream::Chunk::Chunk(){
RTMPStream::Chunk::Chunk() {
headertype = 0;
cs_id = 0;
timestamp = 0;
@ -385,7 +387,7 @@ RTMPStream::Chunk::Chunk(){
} //constructor
/// Packs up a chunk with the given arguments as properties.
std::string & RTMPStream::SendChunk(unsigned int cs_id, unsigned char msg_type_id, unsigned int msg_stream_id, std::string data){
std::string & RTMPStream::SendChunk(unsigned int cs_id, unsigned char msg_type_id, unsigned int msg_stream_id, std::string data) {
static RTMPStream::Chunk ch;
ch.cs_id = cs_id;
ch.timestamp = Util::getMS();
@ -403,7 +405,7 @@ std::string & RTMPStream::SendChunk(unsigned int cs_id, unsigned char msg_type_i
/// \param data Contents of the media data.
/// \param len Length of the media data, in bytes.
/// \param ts Timestamp of the media data, relative to current system time.
std::string & RTMPStream::SendMedia(unsigned char msg_type_id, unsigned char * data, int len, unsigned int ts){
std::string & RTMPStream::SendMedia(unsigned char msg_type_id, unsigned char * data, int len, unsigned int ts) {
static RTMPStream::Chunk ch;
ch.cs_id = msg_type_id + 42;
ch.timestamp = ts;
@ -412,13 +414,13 @@ std::string & RTMPStream::SendMedia(unsigned char msg_type_id, unsigned char * d
ch.len_left = 0;
ch.msg_type_id = msg_type_id;
ch.msg_stream_id = 1;
ch.data = std::string((char*)data, (size_t)len);
ch.data = std::string((char *)data, (size_t)len);
return ch.Pack();
} //SendMedia
/// Packs up a chunk with media contents.
/// \param tag FLV::Tag with media to send.
std::string & RTMPStream::SendMedia(FLV::Tag & tag){
std::string & RTMPStream::SendMedia(FLV::Tag & tag) {
static RTMPStream::Chunk ch;
//Commented bit is more efficient and correct according to RTMP spec.
//Simply passing "4" is the only thing that actually plays correctly, though.
@ -435,7 +437,7 @@ std::string & RTMPStream::SendMedia(FLV::Tag & tag){
} //SendMedia
/// Packs up a chunk for a control message with 1 argument.
std::string & RTMPStream::SendCTL(unsigned char type, unsigned int data){
std::string & RTMPStream::SendCTL(unsigned char type, unsigned int data) {
static RTMPStream::Chunk ch;
ch.cs_id = 2;
ch.timestamp = Util::getMS();
@ -445,12 +447,12 @@ std::string & RTMPStream::SendCTL(unsigned char type, unsigned int data){
ch.msg_type_id = type;
ch.msg_stream_id = 0;
ch.data.resize(4);
*(int*)((char*)ch.data.c_str()) = htonl(data);
*(int *)((char *)ch.data.c_str()) = htonl(data);
return ch.Pack();
} //SendCTL
/// Packs up a chunk for a control message with 2 arguments.
std::string & RTMPStream::SendCTL(unsigned char type, unsigned int data, unsigned char data2){
std::string & RTMPStream::SendCTL(unsigned char type, unsigned int data, unsigned char data2) {
static RTMPStream::Chunk ch;
ch.cs_id = 2;
ch.timestamp = Util::getMS();
@ -460,13 +462,13 @@ std::string & RTMPStream::SendCTL(unsigned char type, unsigned int data, unsigne
ch.msg_type_id = type;
ch.msg_stream_id = 0;
ch.data.resize(5);
*(unsigned int*)((char*)ch.data.c_str()) = htonl(data);
*(unsigned int *)((char *)ch.data.c_str()) = htonl(data);
ch.data[4] = data2;
return ch.Pack();
} //SendCTL
/// Packs up a chunk for a user control message with 1 argument.
std::string & RTMPStream::SendUSR(unsigned char type, unsigned int data){
std::string & RTMPStream::SendUSR(unsigned char type, unsigned int data) {
static RTMPStream::Chunk ch;
ch.cs_id = 2;
ch.timestamp = Util::getMS();
@ -476,14 +478,14 @@ std::string & RTMPStream::SendUSR(unsigned char type, unsigned int data){
ch.msg_type_id = 4;
ch.msg_stream_id = 0;
ch.data.resize(6);
*(unsigned int*)(((char*)ch.data.c_str()) + 2) = htonl(data);
*(unsigned int *)(((char *)ch.data.c_str()) + 2) = htonl(data);
ch.data[0] = 0;
ch.data[1] = type;
return ch.Pack();
} //SendUSR
/// Packs up a chunk for a user control message with 2 arguments.
std::string & RTMPStream::SendUSR(unsigned char type, unsigned int data, unsigned int data2){
std::string & RTMPStream::SendUSR(unsigned char type, unsigned int data, unsigned int data2) {
static RTMPStream::Chunk ch;
ch.cs_id = 2;
ch.timestamp = Util::getMS();
@ -493,8 +495,8 @@ std::string & RTMPStream::SendUSR(unsigned char type, unsigned int data, unsigne
ch.msg_type_id = 4;
ch.msg_stream_id = 0;
ch.data.resize(10);
*(unsigned int*)(((char*)ch.data.c_str()) + 2) = htonl(data);
*(unsigned int*)(((char*)ch.data.c_str()) + 6) = htonl(data2);
*(unsigned int *)(((char *)ch.data.c_str()) + 2) = htonl(data);
*(unsigned int *)(((char *)ch.data.c_str()) + 6) = htonl(data2);
ch.data[0] = 0;
ch.data[1] = type;
return ch.Pack();
@ -508,14 +510,14 @@ std::string & RTMPStream::SendUSR(unsigned char type, unsigned int data, unsigne
/// \param indata The input string to parse and update.
/// \warning This function will destroy the current data in this chunk!
/// \returns True if a whole chunk could be read, false otherwise.
bool RTMPStream::Chunk::Parse(std::string & indata){
gettimeofday( &RTMPStream::lastrec, 0);
bool RTMPStream::Chunk::Parse(std::string & indata) {
gettimeofday(&RTMPStream::lastrec, 0);
unsigned int i = 0;
if (indata.size() < 1) return false; //need at least a byte
unsigned char chunktype = indata[i++ ];
//read the chunkstream ID properly
switch (chunktype & 0x3F){
switch (chunktype & 0x3F) {
case 0:
if (indata.size() < 2) return false; //need at least 2 bytes to continue
cs_id = indata[i++ ] + 64;
@ -535,7 +537,7 @@ bool RTMPStream::Chunk::Parse(std::string & indata){
//process the rest of the header, for each chunk type
headertype = chunktype & 0xC0;
switch (headertype){
switch (headertype) {
case 0x00:
if (indata.size() < i + 11) return false; //can't read whole header
timestamp = indata[i++ ] * 256 * 256;
@ -553,13 +555,13 @@ bool RTMPStream::Chunk::Parse(std::string & indata){
break;
case 0x40:
if (indata.size() < i + 7) return false; //can't read whole header
if (!allow_short){
if (!allow_short) {
DEBUG_MSG(DLVL_WARN, "Warning: Header type 0x40 with no valid previous chunk!");
}
timestamp = indata[i++ ] * 256 * 256;
timestamp += indata[i++ ] * 256;
timestamp += indata[i++ ];
if (timestamp != 0x00ffffff){
if (timestamp != 0x00ffffff) {
timestamp += prev.timestamp;
}
len = indata[i++ ] * 256 * 256;
@ -571,13 +573,13 @@ bool RTMPStream::Chunk::Parse(std::string & indata){
break;
case 0x80:
if (indata.size() < i + 3) return false; //can't read whole header
if (!allow_short){
if (!allow_short) {
DEBUG_MSG(DLVL_WARN, "Warning: Header type 0x80 with no valid previous chunk!");
}
timestamp = indata[i++ ] * 256 * 256;
timestamp += indata[i++ ] * 256;
timestamp += indata[i++ ];
if (timestamp != 0x00ffffff){
if (timestamp != 0x00ffffff) {
timestamp += prev.timestamp;
}
len = prev.len;
@ -586,7 +588,7 @@ bool RTMPStream::Chunk::Parse(std::string & indata){
msg_stream_id = prev.msg_stream_id;
break;
case 0xC0:
if (!allow_short){
if (!allow_short) {
DEBUG_MSG(DLVL_WARN, "Warning: Header type 0xC0 with no valid previous chunk!");
}
timestamp = prev.timestamp;
@ -597,18 +599,18 @@ bool RTMPStream::Chunk::Parse(std::string & indata){
break;
}
//calculate chunk length, real length, and length left till complete
if (len_left > 0){
if (len_left > 0) {
real_len = len_left;
len_left -= real_len;
}else{
} else {
real_len = len;
}
if (real_len > RTMPStream::chunk_rec_max){
if (real_len > RTMPStream::chunk_rec_max) {
len_left += real_len - RTMPStream::chunk_rec_max;
real_len = RTMPStream::chunk_rec_max;
}
//read extended timestamp, if neccesary
if (timestamp == 0x00ffffff){
if (timestamp == 0x00ffffff) {
if (indata.size() < i + 4) return false; //can't read whole header
timestamp = indata[i++ ] * 256 * 256 * 256;
timestamp += indata[i++ ] * 256 * 256;
@ -617,10 +619,10 @@ bool RTMPStream::Chunk::Parse(std::string & indata){
}
//read data if length > 0, and allocate it
if (real_len > 0){
if (prev.len_left > 0){
if (real_len > 0) {
if (prev.len_left > 0) {
data = prev.data;
}else{
} else {
data = "";
}
if (indata.size() < i + real_len) return false; //can't read all data (yet)
@ -628,12 +630,12 @@ bool RTMPStream::Chunk::Parse(std::string & indata){
indata = indata.substr(i + real_len);
lastrecv[cs_id] = *this;
RTMPStream::rec_cnt += i + real_len;
if (len_left == 0){
if (len_left == 0) {
return true;
}else{
} else {
return Parse(indata);
}
}else{
} else {
data = "";
indata = indata.substr(i + real_len);
lastrecv[cs_id] = *this;
@ -650,17 +652,17 @@ bool RTMPStream::Chunk::Parse(std::string & indata){
/// \param buffer The input to parse and update.
/// \warning This function will destroy the current data in this chunk!
/// \returns True if a whole chunk could be read, false otherwise.
bool RTMPStream::Chunk::Parse(Socket::Buffer & buffer){
gettimeofday( &RTMPStream::lastrec, 0);
bool RTMPStream::Chunk::Parse(Socket::Buffer & buffer) {
gettimeofday(&RTMPStream::lastrec, 0);
unsigned int i = 0;
if ( !buffer.available(3)){
if (!buffer.available(3)) {
return false;
} //we want at least 3 bytes
std::string indata = buffer.copy(3);
unsigned char chunktype = indata[i++ ];
//read the chunkstream ID properly
switch (chunktype & 0x3F){
switch (chunktype & 0x3F) {
case 0:
cs_id = indata[i++ ] + 64;
break;
@ -677,9 +679,9 @@ bool RTMPStream::Chunk::Parse(Socket::Buffer & buffer){
//process the rest of the header, for each chunk type
headertype = chunktype & 0xC0;
switch (headertype){
switch (headertype) {
case 0x00:
if ( !buffer.available(i + 11)){
if (!buffer.available(i + 11)) {
return false;
} //can't read whole header
indata = buffer.copy(i + 11);
@ -697,17 +699,17 @@ bool RTMPStream::Chunk::Parse(Socket::Buffer & buffer){
msg_stream_id += indata[i++ ] * 256 * 256 * 256;
break;
case 0x40:
if ( !buffer.available(i + 7)){
if (!buffer.available(i + 7)) {
return false;
} //can't read whole header
indata = buffer.copy(i + 7);
if (prev.msg_type_id == 0){
if (prev.msg_type_id == 0) {
DEBUG_MSG(DLVL_WARN, "Warning: Header type 0x40 with no valid previous chunk!");
}
timestamp = indata[i++ ] * 256 * 256;
timestamp += indata[i++ ] * 256;
timestamp += indata[i++ ];
if (timestamp != 0x00ffffff){
if (timestamp != 0x00ffffff) {
timestamp += prev.timestamp;
}
len = indata[i++ ] * 256 * 256;
@ -718,17 +720,17 @@ bool RTMPStream::Chunk::Parse(Socket::Buffer & buffer){
msg_stream_id = prev.msg_stream_id;
break;
case 0x80:
if ( !buffer.available(i + 3)){
if (!buffer.available(i + 3)) {
return false;
} //can't read whole header
indata = buffer.copy(i + 3);
if (prev.msg_type_id == 0){
if (prev.msg_type_id == 0) {
DEBUG_MSG(DLVL_WARN, "Warning: Header type 0x80 with no valid previous chunk!");
}
timestamp = indata[i++ ] * 256 * 256;
timestamp += indata[i++ ] * 256;
timestamp += indata[i++ ];
if (timestamp != 0x00ffffff){
if (timestamp != 0x00ffffff) {
timestamp += prev.timestamp;
}
len = prev.len;
@ -737,7 +739,7 @@ bool RTMPStream::Chunk::Parse(Socket::Buffer & buffer){
msg_stream_id = prev.msg_stream_id;
break;
case 0xC0:
if (prev.msg_type_id == 0){
if (prev.msg_type_id == 0) {
DEBUG_MSG(DLVL_WARN, "Warning: Header type 0xC0 with no valid previous chunk!");
}
timestamp = prev.timestamp;
@ -748,19 +750,19 @@ bool RTMPStream::Chunk::Parse(Socket::Buffer & buffer){
break;
}
//calculate chunk length, real length, and length left till complete
if (len_left > 0){
if (len_left > 0) {
real_len = len_left;
len_left -= real_len;
}else{
} else {
real_len = len;
}
if (real_len > RTMPStream::chunk_rec_max){
if (real_len > RTMPStream::chunk_rec_max) {
len_left += real_len - RTMPStream::chunk_rec_max;
real_len = RTMPStream::chunk_rec_max;
}
//read extended timestamp, if neccesary
if (timestamp == 0x00ffffff){
if ( !buffer.available(i + 4)){
if (timestamp == 0x00ffffff) {
if (!buffer.available(i + 4)) {
return false;
} //can't read timestamp
indata = buffer.copy(i + 4);
@ -771,24 +773,24 @@ bool RTMPStream::Chunk::Parse(Socket::Buffer & buffer){
}
//read data if length > 0, and allocate it
if (real_len > 0){
if ( !buffer.available(i + real_len)){
if (real_len > 0) {
if (!buffer.available(i + real_len)) {
return false;
} //can't read all data (yet)
buffer.remove(i); //remove the header
if (prev.len_left > 0){
if (prev.len_left > 0) {
data = prev.data + buffer.remove(real_len); //append the data and remove from buffer
}else{
} else {
data = buffer.remove(real_len); //append the data and remove from buffer
}
lastrecv[cs_id] = *this;
RTMPStream::rec_cnt += i + real_len;
if (len_left == 0){
if (len_left == 0) {
return true;
}else{
} else {
return Parse(buffer);
}
}else{
} else {
buffer.remove(i); //remove the header
data = "";
indata = indata.substr(i + real_len);
@ -802,10 +804,10 @@ bool RTMPStream::Chunk::Parse(Socket::Buffer & buffer){
/// After calling this function, don't forget to read and ignore 1536 extra bytes,
/// these are the handshake response and not interesting for us because we don't do client
/// verification.
bool RTMPStream::doHandshake(){
bool RTMPStream::doHandshake() {
char Version;
//Read C0
if (handshake_in.size() < 1537){
if (handshake_in.size() < 1537) {
DEBUG_MSG(DLVL_FAIL, "Handshake wasn't filled properly (%lu/1537) - aborting!", handshake_in.size());
return false;
}
@ -816,9 +818,9 @@ bool RTMPStream::doHandshake(){
RTMPStream::rec_cnt += 1537;
//Build S1 Packet
*((uint32_t*)Server) = 0; //time zero
*(((uint32_t*)(Server + 4))) = htonl(0x01020304); //version 1 2 3 4
for (int i = 8; i < 3072; ++i){
*((uint32_t *)Server) = 0; //time zero
*(((uint32_t *)(Server + 4))) = htonl(0x01020304); //version 1 2 3 4
for (int i = 8; i < 3072; ++i) {
Server[i] = FILLER_DATA[i % sizeof(FILLER_DATA)];
} //"random" data
@ -828,7 +830,7 @@ bool RTMPStream::doHandshake(){
if (ValidateClientScheme(Client, 0)) _validationScheme = 0;
if (ValidateClientScheme(Client, 1)) _validationScheme = 1;
DEBUG_MSG(DLVL_HIGH, "Handshake type is %hhi, encryption is %s", _validationScheme, encrypted?"on":"off");
DEBUG_MSG(DLVL_HIGH, "Handshake type is %hhi, encryption is %s", _validationScheme, encrypted ? "on" : "off");
//FIRST 1536 bytes from server response
//compute DH key position
@ -837,34 +839,34 @@ bool RTMPStream::doHandshake(){
//generate DH key
DHWrapper dhWrapper(1024);
if ( !dhWrapper.Initialize()){
if (!dhWrapper.Initialize()) {
return false;
}
if ( !dhWrapper.CreateSharedKey(Client + clientDHOffset, 128)){
if (!dhWrapper.CreateSharedKey(Client + clientDHOffset, 128)) {
return false;
}
if ( !dhWrapper.CopyPublicKey(Server + serverDHOffset, 128)){
if (!dhWrapper.CopyPublicKey(Server + serverDHOffset, 128)) {
return false;
}
if (encrypted){
if (encrypted) {
uint8_t secretKey[128];
if ( !dhWrapper.CopySharedKey(secretKey, sizeof(secretKey))){
if (!dhWrapper.CopySharedKey(secretKey, sizeof(secretKey))) {
return false;
}
RC4_KEY _pKeyIn;
RC4_KEY _pKeyOut;
InitRC4Encryption(secretKey, (uint8_t*) &Client[clientDHOffset], (uint8_t*) &Server[serverDHOffset], &_pKeyIn, &_pKeyOut);
InitRC4Encryption(secretKey, (uint8_t *) &Client[clientDHOffset], (uint8_t *) &Server[serverDHOffset], &_pKeyIn, &_pKeyOut);
uint8_t data[1536];
RC4( &_pKeyIn, 1536, data, data);
RC4( &_pKeyOut, 1536, data, data);
RC4(&_pKeyIn, 1536, data, data);
RC4(&_pKeyOut, 1536, data, data);
}
//generate the digest
uint32_t serverDigestOffset = GetDigestOffset(Server, _validationScheme);
uint8_t *pTempBuffer = new uint8_t[1536 - 32];
uint8_t * pTempBuffer = new uint8_t[1536 - 32];
memcpy(pTempBuffer, Server, serverDigestOffset);
memcpy(pTempBuffer + serverDigestOffset, Server + serverDigestOffset + 32, 1536 - serverDigestOffset - 32);
uint8_t *pTempHash = new uint8_t[512];
uint8_t * pTempHash = new uint8_t[512];
HMACsha256(pTempBuffer, 1536 - 32, genuineFMSKey, 36, pTempHash);
memcpy(Server + serverDigestOffset, pTempHash, 32);
delete[] pTempBuffer;
@ -874,7 +876,7 @@ bool RTMPStream::doHandshake(){
uint32_t keyChallengeIndex = GetDigestOffset(Client, _validationScheme);
pTempHash = new uint8_t[512];
HMACsha256(Client + keyChallengeIndex, 32, genuineFMSKey, 68, pTempHash);
uint8_t *pLastHash = new uint8_t[512];
uint8_t * pLastHash = new uint8_t[512];
HMACsha256(Server + 1536, 1536 - 32, pTempHash, 32, pLastHash);
memcpy(Server + 1536 * 2 - 32, pLastHash, 32);
delete[] pTempHash;