|
@@ -33,6 +33,7 @@
|
|
|
#include "ListEntry.h"
|
|
|
#include <screencodec.h>
|
|
|
#include "jpeg2k.h"
|
|
|
+#include "chinaEncrypt.h"
|
|
|
|
|
|
#ifdef RVC_OS_WIN
|
|
|
#include <DbgHelp.h>
|
|
@@ -44,6 +45,8 @@
|
|
|
#define DEFAULT_RX_BUF_SIZE 8192
|
|
|
#define KEY_LEN 16
|
|
|
|
|
|
+#define ENCRYPT_CHINA 1
|
|
|
+
|
|
|
#ifndef RVC_OS_WIN
|
|
|
#include "SpBase.h"
|
|
|
|
|
@@ -133,6 +136,7 @@ struct bizchan_t
|
|
|
char remote_pwd[KEY_LEN];
|
|
|
RC4_KEY local_key;
|
|
|
RC4_KEY remote_key;
|
|
|
+ int remote_version;
|
|
|
LARGE_INTEGER last_remote_active_time;
|
|
|
LARGE_INTEGER last_local_active_time;
|
|
|
screen_decoder_session_t *dec_session;
|
|
@@ -151,6 +155,8 @@ static lpfn_cryptionfun encodestring = NULL;
|
|
|
static lpfn_cryptionfun decodestring_mobile = NULL;
|
|
|
static lpfn_cryptionfun encodestring_mobile = NULL;
|
|
|
|
|
|
+static unsigned char seed_key []= {0x81,0x32,0x13,0xf5,0x29,0x3b,0x52,0x37,0x61,0x98,0x33,0x15,0x72,0x31,0xfe,0x34};
|
|
|
+
|
|
|
static __inline unsigned int hash32_buf(const void *bf, size_t len, unsigned int hash)
|
|
|
{
|
|
|
const unsigned char *s = (const unsigned char*)bf;
|
|
@@ -211,6 +217,33 @@ static __inline void GetTick(LARGE_INTEGER *last, LARGE_INTEGER *lt)
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+static void Dbg(bizchan_t *chan, int level, const char *fmt, ...)
|
|
|
+{
|
|
|
+ int n;
|
|
|
+ va_list arg;
|
|
|
+ va_start(arg, fmt);
|
|
|
+ if (chan->cb.dbg) {
|
|
|
+ n = _vscprintf(fmt, arg);
|
|
|
+ if (n > 0) {
|
|
|
+ char *buf = (char*)_alloca((size_t)(n + 3));
|
|
|
+ vsprintf(buf, fmt, arg);
|
|
|
+ (*chan->cb.dbg)(chan, level, buf, chan->cb.user_data);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ n = _vscprintf(fmt, arg);
|
|
|
+ if (n > 0) {
|
|
|
+ char *buf = (char*)_alloca((size_t)(n + 3));
|
|
|
+ vsprintf(buf, fmt, arg);
|
|
|
+ strcat(buf, "\r\n");
|
|
|
+ OutputDebugStringA((LPCSTR)buf);
|
|
|
+ printf(buf);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ va_end(arg);
|
|
|
+}
|
|
|
+
|
|
|
BIZCHAN_API(int) bizchan_lib_init()
|
|
|
{
|
|
|
#ifdef RVC_OS_WIN
|
|
@@ -290,18 +323,14 @@ static int callback_check(const bizchan_callback_t *cb)
|
|
|
|
|
|
static void invoke_on_connect(bizchan_t *chan, int error)
|
|
|
{
|
|
|
- char buffer[128];
|
|
|
- if (error == 0) {
|
|
|
- snprintf(buffer, 128, "b_primary_server: %d, proxy_server:%s", chan->b_primary_server, chan->config.proxy_server);
|
|
|
- chan->cb.dbg(chan, 0, buffer, chan->cb.user_data);
|
|
|
- chan->cb.on_connect(chan,
|
|
|
- error,
|
|
|
+ if (error == 0)
|
|
|
+ chan->cb.on_connect(chan,
|
|
|
+ error,
|
|
|
chan->b_primary_server ? chan->config.proxy_server : chan->config.bak_proxy_server,
|
|
|
- chan->remote_video_rtp_port,
|
|
|
- chan->remote_video_desc,
|
|
|
+ chan->remote_video_rtp_port,
|
|
|
+ chan->remote_video_desc,
|
|
|
chan->remote_client_id,
|
|
|
chan->cb.user_data);
|
|
|
- }
|
|
|
else
|
|
|
chan->cb.on_connect(chan,
|
|
|
error,
|
|
@@ -332,6 +361,7 @@ static void invoke_on_recv_pkt(bizchan_t *chan, int type, int sub_type, int id,
|
|
|
fflush(rx_log_fp);
|
|
|
}*/
|
|
|
|
|
|
+ //Dbg(chan, "invoke_on_recv_pkt, type:%d, sub_type:%d, id:%d, pkt_size:%d", type, sub_type, id, pkt_size);
|
|
|
if (type == ACM_TYPE_SRN) {
|
|
|
int cat = ACM_SRN_CAT(sub_type);
|
|
|
if (cat == ACM_SRN_ANS) {
|
|
@@ -396,9 +426,10 @@ static void invoke_on_recv_pkt(bizchan_t *chan, int type, int sub_type, int id,
|
|
|
} else if (type == ACM_TYPE_SYNC) {
|
|
|
if (chan->winsync_on_recv_cb) {
|
|
|
chan->winsync_on_recv_cb(sub_type, pkt, pkt_size, chan->winsync_user_data);
|
|
|
- } else {
|
|
|
- chan->cb.on_recv_pkt(chan, type, sub_type, id, pkt, pkt_size, chan->cb.user_data);
|
|
|
}
|
|
|
+ //同时上报应用层,用于应用层判断采用哪种同步方式(Sivilight或者chrome H5)
|
|
|
+ chan->cb.on_recv_pkt(chan, type, sub_type, id, pkt, pkt_size, chan->cb.user_data);
|
|
|
+
|
|
|
} else if (type == ACM_TYPE_MODE) {
|
|
|
if (chan->mode_cb) {
|
|
|
chan->mode_cb(TRUE, chan->winsync_user_data);
|
|
@@ -455,49 +486,57 @@ static int on_recv2(bizchan_t *chan, SOCKET conn)
|
|
|
|
|
|
static int on_recv(bizchan_t *chan, SOCKET conn)
|
|
|
{
|
|
|
- char buffer[128];
|
|
|
recv_info_t *ri = &chan->recv_info;
|
|
|
int n;
|
|
|
int result = 0;
|
|
|
|
|
|
do {
|
|
|
- chan->cb.dbg(chan, 0, "on_recv start", chan->cb.user_data);
|
|
|
n = recv(conn, ri->buf+ri->offset, ri->buf_len-ri->offset, 0);
|
|
|
- snprintf(buffer, 128, "on_recv n:%d, ri->offset:%d, ri->buf_len:%d, sizeof(acm_hdr):%d", n, ri->offset, ri->buf_len, sizeof(acm_hdr));
|
|
|
- chan->cb.dbg(chan, 0, buffer, chan->cb.user_data);
|
|
|
+ Dbg(chan, 0, "on_recv n:%d, ri->offset:%d, ri->buf_len:%d, sizeof(acm_hdr):%d", n, ri->offset, ri->buf_len, sizeof(acm_hdr));
|
|
|
if (n > 0) {
|
|
|
int i = 0;
|
|
|
ri->offset += n;
|
|
|
GetTick(&chan->last_remote_active_time, &chan->last_remote_active_time);
|
|
|
while (ri->offset-i >= sizeof(acm_hdr)) {
|
|
|
acm_hdr *hdr = (acm_hdr*)&ri->buf[i];
|
|
|
+ //Dbg(chan, "on_recv, i:%d offset:%d, recv_length:%d", i, ri->offset, n);
|
|
|
+ //Dbg(chan, "on_recv, encrypt:%u, type:%u, sub_type:%u, length:%lu, compress:%u", hdr->encrypt, hdr->type, hdr->sub_type, hdr->length, hdr->compress);
|
|
|
if (hdr->length == 0) {
|
|
|
printf("broken");
|
|
|
}
|
|
|
- snprintf(buffer, 128, "on_recv length:%d, encrypt:%d, compress:%d", hdr->length, hdr->encrypt, hdr->compress);
|
|
|
- chan->cb.dbg(chan, 0, buffer, chan->cb.user_data);
|
|
|
if (ri->offset-i >= hdr->length+sizeof(acm_hdr)) {
|
|
|
- if (hdr->encrypt) {
|
|
|
+ if (hdr->encrypt)
|
|
|
+ {
|
|
|
+ int dec_length = hdr->length;
|
|
|
char *dec_buf = (char*)malloc(hdr->length);
|
|
|
- RC4_set_key(&chan->remote_key, sizeof(chan->remote_pwd), (unsigned char*)chan->remote_pwd);
|
|
|
- RC4(&chan->remote_key, hdr->length, (const unsigned char*)(&hdr->data[0]), (unsigned char*)dec_buf);
|
|
|
- if (hdr->compress) {
|
|
|
+ int sm4_dec_result = DecStrWithSM4_ECB(chan->remote_pwd, sizeof(chan->remote_pwd), (unsigned char*)(&hdr->data[0]), hdr->length, (unsigned char*)dec_buf, &dec_length);
|
|
|
+ if (sm4_dec_result != 0){
|
|
|
+ //Dbg(chan, "DecStrWithSM4_ECB failed, type:%u, sub_type:%u, length:%lu", hdr->type, hdr->sub_type, hdr->length);
|
|
|
+ RC4_set_key(&chan->remote_key, sizeof(chan->remote_pwd), (unsigned char*)chan->remote_pwd);
|
|
|
+ RC4(&chan->remote_key, hdr->length, (const unsigned char*)(&hdr->data[0]), (unsigned char*)dec_buf);
|
|
|
+ dec_length = hdr->length;
|
|
|
+ }
|
|
|
+ if (hdr->compress)
|
|
|
+ {
|
|
|
int len = (int)qlz_size_decompressed(dec_buf);
|
|
|
char *unzip_buf = (char*)malloc(len);
|
|
|
len = qlz_decompress(dec_buf, unzip_buf, &ri->decompress_state);
|
|
|
- if (check_hash(unzip_buf, len, hdr->hash)) {
|
|
|
+ if (check_hash(unzip_buf, len, hdr->hash))
|
|
|
+ {
|
|
|
invoke_on_recv_pkt(chan, hdr->type, hdr->sub_type, hdr->id, unzip_buf, len);
|
|
|
} else {
|
|
|
- OutputDebugStringA("pkt hash failed!\n");
|
|
|
- chan->cb.dbg(chan, 0, "pkt hash failed! 1", chan->cb.user_data);
|
|
|
+ //OutputDebugStringA("pkt hash failed!\n");
|
|
|
+ Dbg(chan, 0, "encrypt compress pkt hash failed! type:%u, sub_type:%u, length:%lu, hash:%lu, unzip:%d", hdr->type, hdr->sub_type, hdr->length, hdr->hash, len);
|
|
|
}
|
|
|
free(unzip_buf);
|
|
|
} else {
|
|
|
- if (check_hash(dec_buf, hdr->length, hdr->hash)) {
|
|
|
- invoke_on_recv_pkt(chan, hdr->type, hdr->sub_type, hdr->id, dec_buf, hdr->length);
|
|
|
- } else {
|
|
|
- OutputDebugStringA("pkt hash failed!\n");
|
|
|
- chan->cb.dbg(chan, 0, "pkt hash failed! 2", chan->cb.user_data);
|
|
|
+ //sm4解密后hdr->length长度与内容长度不一致,采用dec_length变量
|
|
|
+ if (check_hash(dec_buf, dec_length, hdr->hash)) {
|
|
|
+ invoke_on_recv_pkt(chan, hdr->type, hdr->sub_type, hdr->id, dec_buf, dec_length);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ //OutputDebugStringA("pkt hash failed!\n");
|
|
|
+ Dbg(chan, 0, "encrypt uncompress pkt hash failed! type:%u, sub_type:%u, length:%lu, hash:%lu", hdr->type, hdr->sub_type, hdr->length, hdr->hash);
|
|
|
}
|
|
|
}
|
|
|
free(dec_buf);
|
|
@@ -509,16 +548,16 @@ static int on_recv(bizchan_t *chan, SOCKET conn)
|
|
|
if (check_hash(unzip_buf, len, hdr->hash)) {
|
|
|
invoke_on_recv_pkt(chan, hdr->type, hdr->sub_type, hdr->id, unzip_buf, len);
|
|
|
} else {
|
|
|
- OutputDebugStringA("pkt hash failed!\n");
|
|
|
- chan->cb.dbg(chan, 0, "pkt hash failed! 3", chan->cb.user_data);
|
|
|
+ //OutputDebugStringA("pkt hash failed!\n");
|
|
|
+ Dbg(chan, 0, "compress pkt hash failed! type:%u, sub_type:%u, length:%lu, hash:%lu, unzip:%d", hdr->type, hdr->sub_type, hdr->length, hdr->hash, len);
|
|
|
}
|
|
|
free(unzip_buf);
|
|
|
} else {
|
|
|
if (check_hash((char*)&hdr->data[0], hdr->length, hdr->hash)) {
|
|
|
invoke_on_recv_pkt(chan, hdr->type, hdr->sub_type, hdr->id, (const char*)&hdr->data[0], hdr->length);
|
|
|
} else {
|
|
|
- OutputDebugStringA("pkt hash failed!\n");
|
|
|
- chan->cb.dbg(chan, 0, "pkt hash failed! 4", chan->cb.user_data);
|
|
|
+ //OutputDebugStringA("pkt hash failed!\n");
|
|
|
+ Dbg(chan, 0, "uncompress pkt hash failed! type:%u, sub_type:%u, length:%lu, hash:%lu", hdr->type, hdr->sub_type, hdr->length, hdr->hash);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -547,15 +586,14 @@ static int on_recv(bizchan_t *chan, SOCKET conn)
|
|
|
else {
|
|
|
result = (n < 0 || (errno == EWOULDBLOCK) || (errno == EINTR) || (errno == EAGAIN)) ? 0 : -1;
|
|
|
}
|
|
|
- snprintf(buffer, 128, "on_recv n:%d, result:%d, errno:%d", n, result, errno);
|
|
|
- chan->cb.dbg(chan, 0, buffer, chan->cb.user_data);
|
|
|
+
|
|
|
+ Dbg(chan, 0, "on_recv n:%d, result:%d, errno:%d", n, result, errno);
|
|
|
return result;
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
static int on_send(bizchan_t *chan, SOCKET conn)
|
|
|
{
|
|
|
- char buffer[128];
|
|
|
send_info_t *si = &chan->send_info;
|
|
|
int n = 1;//默认为1
|
|
|
int result = -1;
|
|
@@ -569,22 +607,31 @@ static int on_send(bizchan_t *chan, SOCKET conn)
|
|
|
do {
|
|
|
send_buf_node *t = CONTAINING_RECORD(ListEntry_GetHead(&si->send_list), send_buf_node, entry);
|
|
|
if (t->need_encrypt) {
|
|
|
+ //SM4加密,密文会比明文长16字节
|
|
|
+ int enc_length = t->left + sizeof(acm_hdr)+16;
|
|
|
acm_hdr *hdr = (acm_hdr*)t->buf;
|
|
|
- char *enc_buf = (char*)malloc(t->left+sizeof(acm_hdr));
|
|
|
- RC4_set_key(&chan->local_key, sizeof(chan->local_pwd), (unsigned char*)chan->local_pwd);
|
|
|
- RC4(&chan->local_key, t->left, (const unsigned char*)(&hdr->data[0]), (unsigned char*)(enc_buf+sizeof(acm_hdr)));
|
|
|
+ char *enc_buf = (char*)malloc(t->left+sizeof(acm_hdr) + 16);
|
|
|
+ //version为2代表支持国密,采用SM4加密
|
|
|
+ if(chan->remote_version != 1){
|
|
|
+ EncStrWithSM4_ECB(chan->local_pwd, sizeof(chan->local_pwd), (unsigned char*)(&hdr->data[0]), hdr->length, (unsigned char*)(enc_buf+sizeof(acm_hdr)), &enc_length);
|
|
|
+ hdr->length = enc_length;
|
|
|
+ t->left = enc_length + sizeof(acm_hdr);
|
|
|
+ //Dbg(chan, "enc_length:%d", enc_length);
|
|
|
+ } else {
|
|
|
+ RC4_set_key(&chan->local_key, sizeof(chan->local_pwd), (unsigned char*)chan->local_pwd);
|
|
|
+ RC4(&chan->local_key, t->left, (const unsigned char*)(&hdr->data[0]), (unsigned char*)(enc_buf+sizeof(acm_hdr)));
|
|
|
+ }
|
|
|
memcpy(enc_buf, hdr, sizeof(acm_hdr));
|
|
|
free(t->buf);
|
|
|
t->buf = enc_buf;
|
|
|
t->need_encrypt = 0;
|
|
|
}
|
|
|
n = send(conn, t->buf+t->sended, t->left, 0);
|
|
|
- snprintf(buffer, 128, "on_send n:%d, t->sended:%d, t->left:%d", n, t->sended, t->left);
|
|
|
- chan->cb.dbg(chan, 0, buffer, chan->cb.user_data);
|
|
|
+ Dbg(chan, 0, "on_send n:%d, t->sended:%d, t->left:%d", n, t->sended, t->left);
|
|
|
if (n > 0) {
|
|
|
char tmp[32];
|
|
|
sprintf(tmp, "send out %d bytes!\n", n);
|
|
|
- OutputDebugStringA(tmp);
|
|
|
+ //OutputDebugStringA(tmp);
|
|
|
t->left -= n;
|
|
|
t->sended += n;
|
|
|
if (t->left == 0) {
|
|
@@ -742,13 +789,22 @@ static void process(bizchan_t *chan)
|
|
|
{
|
|
|
error = netevents.iErrorCode[FD_WRITE_BIT];
|
|
|
if (error == 0) {
|
|
|
+ int enc_length = KEY_LEN;
|
|
|
proxy_hdr hdr = {0};
|
|
|
hdr.tag[0] = 'A';
|
|
|
hdr.tag[1] = 'C';
|
|
|
hdr.tag[2] = 'M';
|
|
|
hdr.version = ACM_PROTOCOL_VERSION;
|
|
|
- generate_rand_key(chan->local_pwd, sizeof(chan->local_pwd));
|
|
|
+ generate_rand_key(chan->local_pwd, KEY_LEN/2);
|
|
|
+ //等待全部升级后再采用SM4加密
|
|
|
+ #if ENCRYPT_CHINA
|
|
|
+ EncWithSM4_ECB(seed_key, (unsigned char*)&chan->local_pwd[0], KEY_LEN / 2,
|
|
|
+ (unsigned char*)&hdr.encrypt_key[0], &enc_length);
|
|
|
+ Dbg(chan, "use SM4 password_crypt_type");
|
|
|
+ #else
|
|
|
encodefun((unsigned char*)&hdr.encrypt_key[0], sizeof(hdr.encrypt_key), (unsigned char*)&chan->local_pwd[0], sizeof(chan->local_pwd));
|
|
|
+ Dbg(chan, "use old password_crypt_type");
|
|
|
+ #endif
|
|
|
hdr.encrypt_keyhash = hash_key(chan->local_pwd, sizeof(chan->local_pwd));
|
|
|
memset(hdr.callee_id, ' ', sizeof(hdr.callee_id));
|
|
|
memset(hdr.caller_id, ' ', sizeof(hdr.caller_id));
|
|
@@ -787,11 +843,21 @@ static void process(bizchan_t *chan)
|
|
|
if (t > 0) {
|
|
|
ack_hdr_recv_bytes += t;
|
|
|
if (ack_hdr_recv_bytes == sizeof(ack_hdr)) {
|
|
|
- decodefun((unsigned char*)&chan->remote_pwd[0], sizeof(chan->remote_pwd), (unsigned char*)&ack_hdr.encrypt_key[0], sizeof(ack_hdr.encrypt_key));
|
|
|
+ int dec_length = KEY_LEN;
|
|
|
+ int result = DecWithSM4_ECB(seed_key,
|
|
|
+ (unsigned char*)&ack_hdr.encrypt_key[0], sizeof(ack_hdr.encrypt_key),
|
|
|
+ (unsigned char*)&chan->remote_pwd[0], &dec_length);
|
|
|
+ Dbg(chan, "use SM4 Decode password result:%d", result);
|
|
|
+ if(result != 0){
|
|
|
+ result = decodefun((unsigned char*)&chan->remote_pwd[0], sizeof(chan->remote_pwd), (unsigned char*)&ack_hdr.encrypt_key[0], sizeof(ack_hdr.encrypt_key));
|
|
|
+ Dbg(chan, "use old Decode password result:%d", result);
|
|
|
+ }
|
|
|
if (check_hash(chan->remote_pwd, sizeof(chan->remote_pwd), ack_hdr.encrypt_keyhash)) {
|
|
|
chan->remote_video_rtp_port = ack_hdr.rtp_port;
|
|
|
chan->remote_video_desc = ack_hdr.media_desc;
|
|
|
memcpy(chan->remote_client_id, ack_hdr.client_id, sizeof(chan->remote_client_id));
|
|
|
+ chan->remote_version = ack_hdr.version;
|
|
|
+ Dbg(chan, "remote_acm_version:%d", chan->remote_version);
|
|
|
chan->connected = TRUE;
|
|
|
break;
|
|
|
} else {
|
|
@@ -838,7 +904,8 @@ static void process(bizchan_t *chan)
|
|
|
rc = on_send(chan, conn);
|
|
|
if (rc != 0)
|
|
|
break;
|
|
|
- } else if (dwRet == WAIT_OBJECT_0+1)
|
|
|
+ }
|
|
|
+ else if (dwRet == WAIT_OBJECT_0+1)
|
|
|
{
|
|
|
WSANETWORKEVENTS netevents;
|
|
|
if (WSAEnumNetworkEvents(conn, evts[1], &netevents) != SOCKET_ERROR)
|
|
@@ -854,7 +921,9 @@ static void process(bizchan_t *chan)
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
- } else if (dwRet == WAIT_TIMEOUT) {
|
|
|
+ }
|
|
|
+ else if (dwRet == WAIT_TIMEOUT)
|
|
|
+ {
|
|
|
LARGE_INTEGER now;
|
|
|
GetTick(&chan->last_remote_active_time, &now);
|
|
|
if (now.QuadPart - chan->last_remote_active_time.QuadPart >= PING_INTERVAL) {
|
|
@@ -872,12 +941,14 @@ static void process(bizchan_t *chan)
|
|
|
}
|
|
|
|
|
|
on_error:
|
|
|
- OutputDebugStringA("on_error");
|
|
|
+ //OutputDebugStringA("on_error");
|
|
|
+ Dbg(chan, "on_error");
|
|
|
if (!chan->connected) {
|
|
|
invoke_on_connect(chan, -1); // connect failed!
|
|
|
} else {
|
|
|
//....
|
|
|
- OutputDebugStringA("connected, and error!");
|
|
|
+ //OutputDebugStringA("connected, and error!");
|
|
|
+ Dbg(chan, "connected, and error!");
|
|
|
}
|
|
|
|
|
|
if (conn != INVALID_SOCKET)
|
|
@@ -900,13 +971,21 @@ static void do_shake_send(bizchan_t* chan, SOCKET conn, int* error) {
|
|
|
decodefun = decodestring_mobile;
|
|
|
}
|
|
|
|
|
|
+ int enc_length = KEY_LEN;
|
|
|
hdr.tag[0] = 'A';
|
|
|
hdr.tag[1] = 'C';
|
|
|
hdr.tag[2] = 'M';
|
|
|
hdr.version = ACM_PROTOCOL_VERSION;
|
|
|
- generate_rand_key(chan->local_pwd, sizeof(chan->local_pwd));
|
|
|
+ generate_rand_key(chan->local_pwd, KEY_LEN / 2);
|
|
|
+ //等待全部升级后再采用SM4加密
|
|
|
+#if ENCRYPT_CHINA
|
|
|
+ EncWithSM4_ECB(seed_key, (unsigned char*)&chan->local_pwd[0], KEY_LEN / 2,
|
|
|
+ (unsigned char*)&hdr.encrypt_key[0], &enc_length);
|
|
|
+ Dbg(chan, 0, "use SM4 password_crypt_type");
|
|
|
+#else
|
|
|
encodefun((unsigned char*)&hdr.encrypt_key[0], sizeof(hdr.encrypt_key), (unsigned char*)&chan->local_pwd[0], sizeof(chan->local_pwd));
|
|
|
-
|
|
|
+ Dbg(chan, 0, "use old password_crypt_type");
|
|
|
+#endif
|
|
|
hdr.encrypt_keyhash = hash_key(chan->local_pwd, sizeof(chan->local_pwd));
|
|
|
memset(hdr.callee_id, ' ', sizeof(hdr.callee_id));
|
|
|
memset(hdr.caller_id, ' ', sizeof(hdr.caller_id));
|
|
@@ -921,6 +1000,7 @@ static void do_shake_send(bizchan_t* chan, SOCKET conn, int* error) {
|
|
|
}
|
|
|
hdr.rtp_port = chan->config.video.rtp_port;
|
|
|
hdr.media_desc = chan->config.video.desc;
|
|
|
+
|
|
|
if (send(conn, (char*)&hdr, sizeof(hdr), 0) != sizeof(hdr)) {
|
|
|
*error = -1;
|
|
|
}
|
|
@@ -932,7 +1012,6 @@ static void do_shake_recv(bizchan_t* chan, SOCKET conn, int* error) {
|
|
|
int ack_hdr_recv_bytes = 0;
|
|
|
lpfn_cryptionfun encodefun = encodestring;
|
|
|
lpfn_cryptionfun decodefun = decodestring;
|
|
|
- char buffer[128];
|
|
|
|
|
|
if (1 == chan->config.crypt_type) {
|
|
|
encodefun = encodestring_mobile;
|
|
@@ -947,20 +1026,29 @@ static void do_shake_recv(bizchan_t* chan, SOCKET conn, int* error) {
|
|
|
//chan->cb.dbg(chan, 0, buffer, chan->cb.user_data);
|
|
|
ack_hdr_recv_bytes += t;
|
|
|
if (ack_hdr_recv_bytes == sizeof(ack_hdr)) {
|
|
|
- decodefun((unsigned char*)&chan->remote_pwd[0], sizeof(chan->remote_pwd), (unsigned char*)&ack_hdr.encrypt_key[0], sizeof(ack_hdr.encrypt_key));
|
|
|
- //chan->cb.dbg(chan, 0, "do_shake_recv remote_pwd:", chan->cb.user_data);
|
|
|
- //chan->cb.dbg(chan, 0, chan->remote_pwd, chan->cb.user_data);
|
|
|
+ int dec_length = KEY_LEN;
|
|
|
+ int result = DecWithSM4_ECB(seed_key,
|
|
|
+ (unsigned char*)&ack_hdr.encrypt_key[0], sizeof(ack_hdr.encrypt_key),
|
|
|
+ (unsigned char*)&chan->remote_pwd[0], &dec_length);
|
|
|
+ Dbg(chan, 0, "use SM4 Decode password result:%d", result);
|
|
|
+ if (result != 0) {
|
|
|
+ result = decodefun((unsigned char*)&chan->remote_pwd[0], sizeof(chan->remote_pwd), (unsigned char*)&ack_hdr.encrypt_key[0], sizeof(ack_hdr.encrypt_key));
|
|
|
+ Dbg(chan, 0, "use old Decode password result:%d", result);
|
|
|
+ }
|
|
|
if (check_hash(chan->remote_pwd, sizeof(chan->remote_pwd), ack_hdr.encrypt_keyhash)) {
|
|
|
chan->remote_video_rtp_port = ack_hdr.rtp_port;
|
|
|
chan->remote_video_desc = ack_hdr.media_desc;
|
|
|
memcpy(chan->remote_client_id, ack_hdr.client_id, sizeof(chan->remote_client_id));
|
|
|
+ chan->remote_version = ack_hdr.version;
|
|
|
+ Dbg(chan, 0, "remote_acm_version:%d", chan->remote_version);
|
|
|
chan->connected = TRUE;
|
|
|
break;
|
|
|
}
|
|
|
else {
|
|
|
*error = -1;
|
|
|
- chan->cb.dbg(chan, 0, "do_shake_recv check_hash failed", chan->cb.user_data);
|
|
|
+ Dbg(chan, 0, "do_shake_recv check_hash failed");
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
}
|
|
|
} while (t > 0 && *error == 0);
|
|
@@ -970,9 +1058,8 @@ static void do_shake_recv(bizchan_t* chan, SOCKET conn, int* error) {
|
|
|
#else
|
|
|
if (t <= 0 && ((errno != EWOULDBLOCK) || (errno != EINTR) || (errno != EAGAIN))) {
|
|
|
*error = -1;
|
|
|
- snprintf(buffer, 128, "do_shake_recv errno:%d", errno);
|
|
|
- chan->cb.dbg(chan, 0, buffer, chan->cb.user_data);
|
|
|
- chan->cb.dbg(chan, 0, "do_shake_recv t<=0 failed", chan->cb.user_data);
|
|
|
+ Dbg(chan, 0, "do_shake_recv errno:%d", errno);
|
|
|
+ Dbg(chan, 0, "do_shake_recv t<=0 failed");
|
|
|
}
|
|
|
#endif
|
|
|
}
|
|
@@ -1028,7 +1115,7 @@ SOCKET connect_server(bizchan_t* chan, char* server, int port, int timeout)
|
|
|
#else
|
|
|
close(m_hSocket);
|
|
|
#endif
|
|
|
- chan->cb.dbg(chan, 0, "connect_server set_socket_noblock failed", chan->cb.user_data);
|
|
|
+ Dbg(chan, 0, "connect_server set_socket_noblock failed");
|
|
|
}
|
|
|
|
|
|
addrSrv.sin_family = AF_INET;
|
|
@@ -1036,7 +1123,7 @@ SOCKET connect_server(bizchan_t* chan, char* server, int port, int timeout)
|
|
|
addrSrv.sin_port = htons(port);
|
|
|
int ret = connect(m_hSocket, (struct sockaddr*)&addrSrv, sizeof(addrSrv));
|
|
|
if (ret == 0) {
|
|
|
- chan->cb.dbg(chan, 0, "connect_server connect success 1.", chan->cb.user_data);
|
|
|
+ Dbg(chan, 0, "connect_server connect success 1.");
|
|
|
return m_hSocket;
|
|
|
}
|
|
|
#ifdef RVC_OS_WIN
|
|
@@ -1048,10 +1135,8 @@ SOCKET connect_server(bizchan_t* chan, char* server, int port, int timeout)
|
|
|
#else
|
|
|
//linux下需要检测EINPROGRESS和EINTR
|
|
|
if (ret < 0 && (errno != EINPROGRESS && errno != EINTR)) {
|
|
|
- char buffer[128];
|
|
|
close(m_hSocket);
|
|
|
- snprintf(buffer, 128, "connect_server connect failed, errno: %d", errno);
|
|
|
- chan->cb.dbg(chan, 0, buffer, chan->cb.user_data);
|
|
|
+ Dbg(chan, 0, "connect_server connect failed, errno: %d", errno);
|
|
|
return INVALID_SOCKET;
|
|
|
}
|
|
|
#endif
|
|
@@ -1069,11 +1154,11 @@ SOCKET connect_server(bizchan_t* chan, char* server, int port, int timeout)
|
|
|
#else
|
|
|
close(m_hSocket);
|
|
|
#endif
|
|
|
- chan->cb.dbg(chan, 0, "connect_server connect timeout.", chan->cb.user_data);
|
|
|
+ Dbg(chan, 0, "connect_server connect timeout.");
|
|
|
return INVALID_SOCKET;
|
|
|
}
|
|
|
|
|
|
- chan->cb.dbg(chan, 0, "connect_server connect success 2.", chan->cb.user_data);
|
|
|
+ Dbg(chan, 0, "connect_server connect success 2.");
|
|
|
return m_hSocket;
|
|
|
}
|
|
|
|
|
@@ -1099,18 +1184,18 @@ static void process(bizchan_t* chan) {
|
|
|
#if 0
|
|
|
do_shake_send(chan, conn, &error);
|
|
|
if (error != 0) {
|
|
|
- chan->cb.dbg(chan, 0, "do_shake_send failed", chan->cb.user_data);
|
|
|
+ Dbg(chan, 0, "do_shake_send failed");
|
|
|
goto on_error;
|
|
|
}
|
|
|
do_shake_recv(chan, conn, &error);
|
|
|
if (error != 0) {
|
|
|
- chan->cb.dbg(chan, 0, "do_shake_recv failed", chan->cb.user_data);
|
|
|
+ Dbg(chan, 0, "do_shake_recv failed");
|
|
|
goto on_error;
|
|
|
}
|
|
|
#else
|
|
|
do_shake_send(chan, conn, &error);
|
|
|
if (error != 0) {
|
|
|
- chan->cb.dbg(chan, 0, "do_shake_send failed", chan->cb.user_data);
|
|
|
+ Dbg(chan, 0, "do_shake_send failed");
|
|
|
goto on_error;
|
|
|
}
|
|
|
while (!chan->stop_flag && !chan->connected) {
|
|
@@ -1123,13 +1208,13 @@ static void process(bizchan_t* chan) {
|
|
|
int activity = select(maxfd + 1, &read_fds, &write_fds, &except_fds, &tv);
|
|
|
if (activity == -1) {
|
|
|
perror("select()");
|
|
|
- chan->cb.dbg(chan, 0, "process shake select -1", chan->cb.user_data);
|
|
|
+ Dbg(chan, 0, "process shake select -1");
|
|
|
goto on_error;
|
|
|
}
|
|
|
else if (activity == 0) {
|
|
|
// timeout
|
|
|
printf("select() returns 0.\n");
|
|
|
- chan->cb.dbg(chan, 0, "process shake select 0", chan->cb.user_data);
|
|
|
+ Dbg(chan, 0, "process shake select 0");
|
|
|
goto on_error;
|
|
|
}else {
|
|
|
/* All fd_set's should be checked. */
|
|
@@ -1141,7 +1226,7 @@ static void process(bizchan_t* chan) {
|
|
|
char pipe_read_buffer[4];
|
|
|
int n = read(chan->evt[0], pipe_read_buffer, 4);
|
|
|
if (n < 0) {
|
|
|
- chan->cb.dbg(chan, 0, "process shake pipe read < 0", chan->cb.user_data);
|
|
|
+ Dbg(chan, 0, "process shake pipe read < 0");
|
|
|
}
|
|
|
}
|
|
|
if (FD_ISSET(conn, &except_fds)) {
|
|
@@ -1159,22 +1244,9 @@ static void process(bizchan_t* chan) {
|
|
|
{
|
|
|
char buffer[128];
|
|
|
int rc;
|
|
|
- /*rc = set_socket_noblock(conn);
|
|
|
- if (rc)
|
|
|
- {
|
|
|
- on_close(chan);
|
|
|
- chan->cb.dbg(chan, 2, "set_socket_noblock failed", chan->cb.user_data);
|
|
|
- goto on_error;
|
|
|
- }*/
|
|
|
+
|
|
|
invoke_on_connect(chan, 0);
|
|
|
chan->recv_info.offset = 0;
|
|
|
- /*rc = on_recv(chan, conn);
|
|
|
- if (rc)
|
|
|
- {
|
|
|
- on_close(chan);
|
|
|
- chan->cb.dbg(chan, 2, "on_recv failed", chan->cb.user_data);
|
|
|
- goto on_error;
|
|
|
- }*/
|
|
|
while (!chan->stop_flag)
|
|
|
{
|
|
|
struct timeval tv;
|
|
@@ -1186,7 +1258,7 @@ static void process(bizchan_t* chan) {
|
|
|
int activity = select(maxfd + 1, &read_fds, &write_fds, &except_fds, &tv);
|
|
|
if (activity == -1) {
|
|
|
perror("select()");
|
|
|
- chan->cb.dbg(chan, 0, "chan select() error.", chan->cb.user_data);
|
|
|
+ Dbg(chan, 0, "chan select() error.");
|
|
|
goto on_error;
|
|
|
}
|
|
|
else if (activity == 0) {
|
|
@@ -1218,11 +1290,11 @@ static void process(bizchan_t* chan) {
|
|
|
break;
|
|
|
}
|
|
|
else {
|
|
|
- chan->cb.dbg(chan, 0, "pipe read < 0", chan->cb.user_data);
|
|
|
+ Dbg(chan, 0, "pipe read < 0");
|
|
|
}
|
|
|
}
|
|
|
if (FD_ISSET(conn, &except_fds)) {
|
|
|
- chan->cb.dbg(chan, 0, "select() except_fds set.", chan->cb.user_data);
|
|
|
+ Dbg(chan, 0, "select() except_fds set.");
|
|
|
error = -1;
|
|
|
}
|
|
|
if (error != 0) {
|
|
@@ -1234,16 +1306,16 @@ static void process(bizchan_t* chan) {
|
|
|
}
|
|
|
|
|
|
on_error:
|
|
|
- OutputDebugStringA("on_error");
|
|
|
- chan->cb.dbg(chan, 0, "on_error", chan->cb.user_data);
|
|
|
+ //OutputDebugStringA("on_error");
|
|
|
+ Dbg(chan, 0, "on_error");
|
|
|
|
|
|
if (!chan->connected) {
|
|
|
invoke_on_connect(chan, -1); // connect failed!
|
|
|
}
|
|
|
else {
|
|
|
//....
|
|
|
- OutputDebugStringA("connected, and error!");
|
|
|
- chan->cb.dbg(chan, 0, "connected, and error!", chan->cb.user_data);
|
|
|
+ //OutputDebugStringA("connected, and error!");
|
|
|
+ Dbg(chan, 0, "connected, and error!");
|
|
|
}
|
|
|
|
|
|
if (conn != INVALID_SOCKET) {
|
|
@@ -1271,7 +1343,7 @@ static void* work_proc(void* arg)
|
|
|
//....
|
|
|
}
|
|
|
#else
|
|
|
- chan->cb.dbg(chan, 0, "work_proc start", chan->cb.user_data);
|
|
|
+ Dbg(chan, 0, "work_proc start");
|
|
|
process(chan);
|
|
|
#endif
|
|
|
return 0;
|
|
@@ -1503,14 +1575,14 @@ BIZCHAN_API(int) bizchan_start_connect(bizchan_t *chan)
|
|
|
}
|
|
|
|
|
|
if (chan->work_thread) {
|
|
|
- chan->cb.dbg(chan, 2, "work_thread exsit!!!", chan->cb.user_data);
|
|
|
+ Dbg(chan, 2, "work_thread exsit!!!");
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
#ifdef RVC_OS_WIN
|
|
|
WSAResetEvent(chan->evt);
|
|
|
#endif
|
|
|
- chan->cb.dbg(chan, 0, "bizchan_start_connect 2", chan->cb.user_data);
|
|
|
+ Dbg(chan, 0, "bizchan_start_connect 2");
|
|
|
|
|
|
chan->stop_flag = 0;
|
|
|
chan->connected = 0;
|
|
@@ -1523,22 +1595,22 @@ BIZCHAN_API(int) bizchan_start_connect(bizchan_t *chan)
|
|
|
#else
|
|
|
int err = pthread_create(&chan->work_thread, NULL, work_proc, chan);
|
|
|
if (0 == err) {
|
|
|
- Dbg("create work thread success, %lu.", chan->work_thread);
|
|
|
+ Dbg(chan, 0, "create work thread success, %lu.", chan->work_thread);
|
|
|
}
|
|
|
else {
|
|
|
- Dbg("create work thread failed.");
|
|
|
+ Dbg(chan, 0, "create work thread failed.");
|
|
|
}
|
|
|
#endif // RVC_OS_WIN
|
|
|
|
|
|
// we now return, when connected, on_connect will invoked in work_proc thread
|
|
|
- chan->cb.dbg(chan, 0, "bizchan_start_connect success", chan->cb.user_data);
|
|
|
+ Dbg(chan, 0, "bizchan_start_connect success");
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
BIZCHAN_API(int) bizchan_start_close(bizchan_t *chan)
|
|
|
{
|
|
|
- chan->cb.dbg(chan, 2, "bizchan_start_close", chan->cb.user_data);
|
|
|
+ Dbg(chan, 2, "bizchan_start_close");
|
|
|
chan->stop_flag = 1;
|
|
|
#ifdef RVC_OS_WIN
|
|
|
WSASetEvent(chan->evt);
|