漏洞修复

This commit is contained in:
Saturneric 2019-02-25 17:26:25 +08:00
parent 5d9bdcce0c
commit ba45facdad
11 changed files with 162 additions and 71 deletions

View File

@ -21,15 +21,6 @@
#include "rsa.h"
#include "rng.hpp"
//提示信息打印类函数
namespace error{
void printError(string error_info);
void printWarning(string warning_info);
void printSuccess(string succes_info);
void printRed(string red_info);
}
struct instructions{
int (*unpack)(string, vector<string> &, vector<string> &, vector<string> &) = NULL;
int (*construct)(string, vector<string> &, vector<string> &, vector<string> &) = NULL;

View File

@ -55,6 +55,7 @@ public :
// 临时缓冲区
char buff[BUFSIZ];
SocketServer(int port,bool ipv4){
server_addr.SetIP("127.0.0.1");
server_addr.SetPort(port);
if(ipv4){
ipptl = AF_INET;

View File

@ -181,6 +181,8 @@ struct box_listener{
uint16_t cnt;
// 接收到的分包数量
uint16_t nbn;
//分包来源地址
sockaddr_in address;
// 储存接收到的分包的动态数组
net_box **boxs;
// 合并分包成RawData
@ -221,6 +223,7 @@ struct connection_listener{
Addr client_addr;
aes_key256 key;
pthread_t pid;
void *father_buff;
};
//通用服务器类
@ -307,6 +310,8 @@ protected:
map<uint64_t,client_register *> client_lst;
// 加密端对端报文
list<encrypt_post *>post_lst;
//服务器名
string name;
public:
SQEServer(int port = 9048);
void ProcessPacket(void);
@ -333,7 +338,7 @@ class Client{
// 回复处理列表
list<respond *> res_lst;
// 请求监听端口
uint32_t listen_port;
uint16_t listen_port;
SocketUDPServer socket;
SocketUDPClient send_socket;
// 与服务器建立的稳定链接

View File

@ -44,6 +44,7 @@
#include <rapidjson/document.h>
#include <rapidjson/writer.h>
#include <rapidjson/stringbuffer.h>
#include <rapidjson/prettywriter.h>
using std::string;
@ -65,4 +66,13 @@ typedef unsigned char UByte;
#define RESPOND_TYPE 101
#define ENCRYPT_POST_TYPE 102
//提示信息打印类函数
namespace error {
void printError(string error_info);
void printWarning(string warning_info);
void printSuccess(string succes_info);
void printRed(string red_info);
void printInfo(string info);
}
#endif /* type_h */

View File

@ -14,10 +14,8 @@ Addr::Addr(string ip_addr, int port, bool ipv4){
address.sin_family = AF_INET;
else
address.sin_family = AF_INET6;
address.sin_port = htons(port);
in_addr_t ipu = inet_addr(ip_addr.data());
memcpy(&address.sin_addr, &ipu, sizeof(in_addr_t));
address.sin_port = htons((uint16_t)port);
address.sin_addr.s_addr = inet_addr(ip_addr.data());
addr_size = sizeof(address);
}
@ -49,13 +47,12 @@ void Addr::SetSize(void){
}
void Addr::SetPort(int port){
address.sin_port = htons(port);
address.sin_port = htons((uint16_t)port);
addr_size = sizeof(address);
}
void Addr::SetIP(string ip_addr){
in_addr_t ipu = inet_addr(ip_addr.data());
memcpy(&address.sin_addr, &ipu, sizeof(in_addr_t));
address.sin_addr.s_addr = inet_addr(ip_addr.data());
addr_size = sizeof(address);
}

View File

@ -299,7 +299,7 @@ static void ShiftRows(state_t* state)
static uint8_t xtime(uint8_t x)
{
return ((x<<1) ^ (((x>>7) & 1) * 0x1b));
return (uint8_t)((x<<1) ^ (((x>>7) & 1) * 0x1b));
}
// MixColumns function mixes the columns of the state matrix
@ -558,7 +558,7 @@ void AES_CTR_xcrypt_buffer(struct AES_ctx* ctx, uint8_t* buf, uint32_t length)
ctx->Iv[bi] = 0;
continue;
}
ctx->Iv[bi] += (uint8_t) 1;
ctx->Iv[bi] += 1;
break;
}
bi = 0;

View File

@ -46,7 +46,6 @@ void *clientRespondDeamon(void *pvclt){
if(tlen > 0){
// 记录有效数据包
if(Server::CheckRawMsg(str, tlen)){
raw_data *ptrdt = new raw_data();
Server::ProcessSignedRawMsg(str, tlen, *ptrdt);
ptrdt->address = *(struct sockaddr_in *)taddr.RawObj();
@ -155,6 +154,7 @@ void Client::NewRequest(request **ppreq,string send_ip,int send_port,string type
*ppreq = pnreq;
}
//创建新的对服务器的请求
void Client::NewRequestListener(request *preq, int timeout, void *args, void (*callback)(respond *,void *)){
request_listener *pnrl = new request_listener();
packet npkt;
@ -164,10 +164,12 @@ void Client::NewRequestListener(request *preq, int timeout, void *args, void (*c
pnrl->clicks = 0;
pnrl->p_req = preq;
pnrl->args = args;
SQEServer::Request2Packet(npkt, *preq);
Server::Packet2Rawdata(npkt, pnrl->trwd);
// 检查请求是否要求加密
if(preq->if_encrypt == true){
Server::EncryptRSARawMsg(pnrl->trwd, sqe_pbc);
Server::SignedRawdata(&pnrl->trwd,"RPKT");
}

View File

@ -215,14 +215,19 @@ int set(string instruct, vector<string> &configs, vector<string> &lconfigs, vect
int if_find = sqlite3_column_int(psqlsmt, 0);
if(if_find);
else{
error::printError("Couldn't SET before INIT process.");
error::printError("Couldn't SET before INIT.");
return -1;
}
sqlite3_finalize(psqlsmt);
if(targets[0] == "server"){
if (targets.size() < 3) {
error::printError("Illegal Args.\nFromat set server [server_ip] [server_port].");
return -1;
}
sql_quote = "UPDATE client_info SET msqes_ip = ?1, msqes_port = ?2 WHERE rowid = 1;";
sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail);
//检查广场服务器IP地址是否正确
if(!Addr::checkValidIP(targets[1])){
error::printError("Arg(ipaddr) is abnomal.");
sqlite3_finalize(psqlsmt);
@ -230,7 +235,7 @@ int set(string instruct, vector<string> &configs, vector<string> &lconfigs, vect
return -1;
}
sqlite3_bind_text(psqlsmt, 1, targets[1].data(), -1, SQLITE_TRANSIENT);
//获得广场服务器端口
stringstream ss;
ss<<targets[2];
int port;
@ -243,6 +248,8 @@ int set(string instruct, vector<string> &configs, vector<string> &lconfigs, vect
return -1;
}
sqlite3_bind_int(psqlsmt, 2, port);
//执行数据库指令
int rtn = sqlite3_step(psqlsmt);
if(rtn != SQLITE_DONE){
sql::printError(psql);
@ -250,6 +257,11 @@ int set(string instruct, vector<string> &configs, vector<string> &lconfigs, vect
sqlite3_finalize(psqlsmt);
}
else if (targets[0] == "key"){
if (targets.size() < 3) {
error::printError("Illegal Args.\nFromat set key [key_type] [key]");
return -1;
}
//客户端远程管理口令
if(targets[1] == "admin"){
string hexresult;
SHA1_Easy(hexresult, targets[2]);
@ -264,6 +276,7 @@ int set(string instruct, vector<string> &configs, vector<string> &lconfigs, vect
}
sqlite3_finalize(psqlsmt);
}
//广场服务器访问口令
else if(targets[1] == "server"){
sql_quote = "UPDATE client_info SET msqes_key = ?1 WHERE rowid = 1;";
sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail);
@ -278,6 +291,10 @@ int set(string instruct, vector<string> &configs, vector<string> &lconfigs, vect
return -1;
}
}
else {
error::printError("Operation doesn't make sense.");
return 0;
}
error::printSuccess("Succeed.");
sqlite3_close(psql);
return 0;
@ -287,8 +304,10 @@ int server(string instruct, vector<string> &configs, vector<string> &lconfigs, v
initClock();
setThreadsClock();
if(targets.size() == 0){
Server nsvr;
setServerClock(&nsvr, 3);
//Server nsvr;
//setServerClock(&nsvr, 3);
SQEServer nsvr;
setServerClockForSquare(&nsvr, 3);
}
else{
if(targets[0] == "square"){
@ -363,30 +382,38 @@ int construct(string instruct, vector<string> &configs, vector<string> &lconfigs
}
int client(string instruct, vector<string> &configs, vector<string> &lconfigs, vector<string> &targets){
sqlite3 *psql;
sqlite3_stmt *psqlsmt;
const char *pzTail;
if(sqlite3_open("info.db", &psql) == SQLITE_ERROR){
sql::printError(psql);
return -1;
}
// 初始化时钟
initClock();
setThreadsClock();
// 建立客户端
Client nclt(9050);
bool if_setip = false;
string set_ip;
if(config_search(configs, "-p")){
set_ip = targets[0];
printf("Set IP: %s\n",set_ip.data());
if_setip = true;
}
setClientClock(&nclt, 3);
request *preq;
// 获得主广场服务器的通信公钥
string sql_quote = "select count(*) from client_info where rowid = 1 and msqes_rsa_public is null;";
sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail);
@ -403,12 +430,17 @@ int client(string instruct, vector<string> &configs, vector<string> &lconfigs, v
msqe_ip = (const char *)sqlite3_column_text(psqlsmt, 0);
msqe_port = sqlite3_column_int(psqlsmt, 1);
sqlite3_finalize(psqlsmt);
error::printSuccess("Main Server IP: " + msqe_ip);
error::printSuccess("Main Server Port: " + std::to_string(msqe_port));
// 如果本地没有主广场服务器的公钥
if(if_null){
//向广场服务器申请通信公钥
nclt.NewRequest(&preq, msqe_ip, msqe_port, "public request", "request for public key");
nclt.NewRequestListener(preq, 30, psql, getSQEPublicKey);
if_wait = 1;
//等待广场服务器回应
while (if_wait == 1) {
sleep(10);
}
@ -416,15 +448,18 @@ int client(string instruct, vector<string> &configs, vector<string> &lconfigs, v
#ifdef DEBUG
printf("Succeed In Getting Rsa Public Key From SQEServer.\n");
#endif
error::printSuccess("Succeed In Requesting Public Key.");
}
else{
#ifdef DEBUG
printf("Error In Getting Rsa Public Key From SQEServer.\n");
#endif
error::printError("Fail To Request Public Key.");
throw "connection error";
return -1;
}
}
// 获得与广场服务器的通信的公钥
sql_quote = "select msqes_rsa_public from client_info where rowid = 1;";
sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail);
@ -440,7 +475,8 @@ int client(string instruct, vector<string> &configs, vector<string> &lconfigs, v
Document reqdata;
if(reqdata.Parse(reqstr.data()).HasParseError()) throw "fail to parse into json";
// key
// 生成并传递端对端加密报文密钥
reqdata["key"].SetArray();
Value &tmp_key = reqdata["key"];
const uint8_t *p_key = naeskey.GetKey();
@ -449,60 +485,77 @@ int client(string instruct, vector<string> &configs, vector<string> &lconfigs, v
tmp_key.PushBack(p_key[idx],allocator);
}
reqdata["name"].SetString(nclt.name.data(),(uint32_t)nclt.name.size());
reqdata["tag"].SetString(nclt.tag.data(),(uint32_t)nclt.name.size());
reqdata["sqe_key"].SetString(nclt.sqe_key.data(), (uint32_t)nclt.sqe_key.size());
reqdata["listen_port"].SetInt(9053);
reqdata["name"].SetString(nclt.name.data(),(uint32_t)nclt.name.size());
reqdata["tag"].SetString(nclt.tag.data(),(uint32_t)nclt.tag.size());
reqdata["sqe_key"].SetString(nclt.sqe_key.data(), (uint32_t)nclt.sqe_key.size());
//设置TCP监听端口
reqdata["listen_port"].SetInt(9052);
//如果强制指定客户端IP地址
string ip;
if(if_setip) ip = set_ip;
else ip = inet_ntoa(nclt.server_cnt->GetAddr().Obj()->sin_addr);
else ip = "127.0.0.1";
reqdata["listen_ip"].SetString(ip.data(),(uint32_t)ip.size());
//构造请求
StringBuffer strbuff;
Writer<StringBuffer> writer(strbuff);
Writer<StringBuffer> writer(strbuff);
reqdata.Accept(writer);
string json_str = strbuff.GetString();
printf("JSON: %s\n",json_str.data());
printf("Connecting...\n");
// 已获得主广场服务器的密钥,进行启动客户端守护进程前的准备工作
nclt.NewRequest(&preq, msqe_ip, msqe_port, "private request", json_str, true);
nclt.NewRequestListener(preq, 99, psql,registerSQECallback);
nclt.NewRequestListener(preq, 44, psql,registerSQECallback);
//等待主广场服务器回应
if_wait = 1;
while (if_wait) {
while (if_wait == 1) {
sleep(1);
}
if (!if_wait) {
// 成功注册
printf("Wait for server to connect\n");
// 创建守护进程
// 成功注册
printf("Get Respond From Server.\n");
// 创建守护进程
int shmid = shmget((key_t)9058, 1024, 0666|IPC_CREAT);
if(shmid == -1){
printf("SHMAT Failed.\n");
}
pid_t fpid = fork();
if(fpid == 0){
//守护进程
printf("Client Register Deamon Has Been Created.");
nclt.server_cnt = new SocketTCPCServer(9053);
nclt.server_cnt = new SocketTCPCServer(9052);
nclt.server_cnt->Listen();
// 获得共享内存地址
Byte *buff = (Byte *)shmat(shmid, NULL, 0);
if(shmid == -1){
printf("SHMAT Failed.\n");
}
while (1) {
if(!memcmp(buff, "SEND", sizeof(uint32_t))){
printf("Get Sending Raw Data\n");
memset(buff, 0, sizeof(uint32_t));
//检测父进程信号
if(!memcmp(buff, "Exit", sizeof(uint32_t))){
error::printInfo("get killing signal.");
//断开共享内存连接
shmdt(buff);
exit(0);
}
nclt.server_cnt->Accept();
//printf("Get connection request from server.\n");
connection_listener *pncl = new connection_listener();
pncl->client_addr = nclt.server_cnt->GetClientAddr();
pncl->data_sfd = nclt.server_cnt->GetDataSFD();
pncl->key = nclt.post_key;
pncl->father_buff = buff;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
@ -512,24 +565,35 @@ int client(string instruct, vector<string> &configs, vector<string> &lconfigs, v
}
}
else{
// 父进程
//父进程
//创建并获得共享内存地址
int shmid = shmget((key_t)9058, 1024, 0666|IPC_CREAT);
Byte *buff = (Byte *)shmat(shmid, 0, 0);
printf("Net Command line: \n");
while (1) {
if (!memcmp(buff, "D_OK", sizeof(uint32_t))) {
memset(buff, 0, sizeof(uint32_t));
break;
}
usleep(1000);
}
error::printSuccess("\nShell For Client: ");
while (1) {
char cmd[1024];
printf(">");
scanf("%s", cmd);
fgets(cmd,1024,stdin);
string cmdstr = cmd;
if(cmdstr == "send"){
memcpy(buff, "SEND", sizeof(uint32_t));
if(cmdstr == "Exit"){
memcpy(buff, "Exit", sizeof(uint32_t));
}
}
}
}
return 0;
}

View File

@ -23,6 +23,9 @@ namespace error {
void printRed(string red_info) {
printf("\033[31m%s\n\033[0m", red_info.data());
}
void printInfo(string info) {
printf("%s\n", info.data());
}
}
bool config_search(vector<string> &configs,string tfg){
@ -88,11 +91,11 @@ void *connectionDeamon(void *args){
Server::ProcessSignedRawMsg(buff, size, *pnrwd);
if(!memcmp(&pnrwd->info, "LCNT", sizeof(uint32_t))){
if_sm = false;
printf("Long Connection From Server\n");
printf("Long Connection From Server.\n");
}
else if(!memcmp(&pnrwd->info, "SCNT", sizeof(uint32_t))){
if_sm = true;
printf("Short Connection From Server\n");
printf("Short Connection From Server.\n");
}
else if(!memcmp(&pnrwd->info, "CNTL", sizeof(uint32_t))){
if_sm = true;
@ -102,14 +105,14 @@ void *connectionDeamon(void *args){
pthread_exit(NULL);
}
else{
printf("Connection illegal\n");
printf("Connection illegal.\n");
delete pnrwd;
pthread_exit(NULL);
}
}
else{
printf("Connection illegal\n");
printf("Connection illegal.\n");
delete pnrwd;
pthread_exit(NULL);
}
@ -132,7 +135,8 @@ void *connectionDeamon(void *args){
Document ndoc;
ndoc.Parse(jres_str.data());
if(ndoc["status"].GetString() == string("ok")){
printf("Register Successful.\n");
error::printSuccess("Register Successful.");
memcpy(pcntl->father_buff,"D_OK", sizeof(uint32_t));
}
}
}

View File

@ -38,7 +38,7 @@ long long ExtEuclid(long long a, long long b)
return y;
}
long long rsa_modExp(long long b, long long e, long long m)
long long rsa_modExp(unsigned long long b, unsigned long long e, unsigned long long m)
{
if (b < 0 || e < 0 || m <= 0){
exit(1);
@ -164,8 +164,7 @@ unsigned char *rsa_decrypt(const uint64_t *message, const unsigned long message_
unsigned char *decrypted = (unsigned char *) malloc(message_size/sizeof(uint64_t));
unsigned char *temp = (unsigned char *) malloc(message_size);
if((decrypted == NULL) || (temp == NULL)){
fprintf(stderr,
"Error: Heap allocation failed.\n");
fprintf(stderr,"Error: Heap allocation failed.\n");
return NULL;
}
// Now we go through each 8-byte chunk and decrypt it.

View File

@ -79,6 +79,7 @@ void setServerClockForSquare(SQEServer *psvr, int clicks){
setServerClock(psvr, clicks);
pthread_mutex_init(&mutex_pktreq, NULL);
pthread_mutex_init(&mutex_cltreg, NULL);
// 注册标准数据包处理守护时钟
clock_register *pncr = new clock_register();
pncr->if_thread = true;
@ -98,6 +99,7 @@ void setServerClockForSquare(SQEServer *psvr, int clicks){
pncr->func = requestProcessorDeamonForSquare;
pncr->arg = (void *)psvr;
newClock(pncr);
error::printSuccess("Server Started...");
}
Server::Server(int port, string send_ip,int send_port):socket(port),send_socket(send_ip,send_port){
@ -289,6 +291,7 @@ void Client::SendRawData(raw_data *trdt){
int Server::SentRawdata(struct raw_data *trdt){
// 对大包进行拆分发送
int rtn = 0;
if(trdt->msg_size > 256){
uint64_t aidx = 0,bidx = 0;
int64_t alls = trdt->msg_size;
@ -306,13 +309,15 @@ int Server::SentRawdata(struct raw_data *trdt){
nnb.set(f_byte,bidx-aidx+1);
nnb.build();
send_socket.SendRAW((Byte *)nnb.send_data, nnb.sdt_size);
rtn = send_socket.SendRAW((Byte *)nnb.send_data, nnb.sdt_size);
aidx = bidx+1;
tmp_idx++;
}
}
else send_socket.SendRAW(trdt->msg, trdt->msg_size);
return 0;
else {
rtn = send_socket.SendRAW(trdt->msg, trdt->msg_size);
}
return rtn;
}
void net_box::FreeNetBox(void){
@ -397,6 +402,7 @@ void *serverDeamon(void *pvcti){
if((pnbxl_itr = psvr->boxls.find(pnbx->b_id)) != psvr->boxls.end()){
box_listener *pnbxl = pnbxl_itr->second;
if (pthread_mutex_lock(&mutex_box) != 0) throw "lock error";
if(pnbxl->boxs[pnbx->idx] == nullptr && pnbxl->nbn < pnbxl->cnt){
pnbxl->boxs[pnbx->idx] = pnbx;
@ -412,6 +418,7 @@ void *serverDeamon(void *pvcti){
else{
box_listener *pnbxl = new box_listener();
pnbxl->cnt = pnbx->cnt;
pnbxl->address = *(struct sockaddr_in *)taddr.RawObj();
pnbxl->boxs = (net_box **) malloc(sizeof(net_box *) * pnbxl->cnt);
memset(pnbxl->boxs, 0, sizeof(net_box *) * pnbxl->cnt);
pnbxl->boxs[pnbx->idx] = pnbx;
@ -465,6 +472,7 @@ void *boxProcessorDeamon(void *pvcti){
raw_data *pnrdt = new raw_data();
pboxl->TogtRawData(*pnrdt);
pnrdt->r_id = pboxl->b_id;
pnrdt->address = pboxl->address;
psvr->rawdata_in.push_back(pnrdt);
pboxl->clicks = -1;
pboxl->free_boxs();
@ -632,14 +640,16 @@ void SQEServer::ProcessPacket(void){
}
SQEServer::SQEServer(int port):Server(port){
//连接数据库
if(sqlite3_open("info.db", &psql) == SQLITE_ERROR){
sql::printError(psql);
throw "database is abnormal";
}
sqlite3_stmt *psqlsmt;
const char *pzTail;
// 从数据库获得服务器的公私钥
string sql_quote = "select sqes_public,sqes_private from server_info where rowid = 1;";
// 从数据库获得服务器的公私钥及服务器名
string sql_quote = "select sqes_public,sqes_private,name from server_info where rowid = 1;";
sqlite3_prepare(psql, sql_quote.data(), -1, &psqlsmt, &pzTail);
if(sqlite3_step(psqlsmt) != SQLITE_ROW){
sql::printError(psql);
@ -650,8 +660,13 @@ SQEServer::SQEServer(int port):Server(port){
tbyt = (Byte *)sqlite3_column_blob(psqlsmt, 1);
memcpy(&prc, tbyt, sizeof(private_key_class));
name = (const char *)sqlite3_column_blob(psqlsmt, 2);
sqlite3_finalize(psqlsmt);
//打印关键信息
error::printSuccess("Server Name: "+name);
error::printSuccess("Listen Port: " + std::to_string(port));
sqlite3_finalize(psqlsmt);
}
void SQEServer::Packet2Request(packet &pkt, request &req){
@ -734,13 +749,13 @@ void SQEServer::ProcessRequset(void){
pclr->t_addr.SetIP(jdoc["listen_ip"].GetString());
pclr->t_addr.SetPort(port);
pclr->passwd = rand64();
// 联络程生命周期
// 联络线程生命周期
pclr->click = 9999;
//if(pthread_mutex_lock(&mutex_cltreg) != 0) throw "lock error";
client_lst.insert({pclr->client_id,pclr});
//pthread_mutex_unlock(&mutex_cltreg);
printf("Ready to connect client %s[%s].\n",pclr->name.data(),pclr->tag.data());
printf("Register: %s[%s] IP: %s TCP_Port: %d\n",pclr->name.data(),pclr->tag.data(),jdoc["listen_ip"].GetString(),port);
// 注册客户端联络守护进程
clock_register *pncr = new clock_register();
pncr->if_thread = true;
@ -827,7 +842,10 @@ void Server::ProcessSendPackets(void){
Packet2Rawdata(*ppkt, nrwd);
SignedRawdata(&nrwd, "SPKT");
send_socket.SetSendSockAddr(ppkt->address);
SentRawdata(&nrwd);
if (SentRawdata(&nrwd) < 0) {
error::printError("fail to send package.");
perror("sendto");
}
freeRawdataServer(nrwd);
freePcaketServer(*ppkt);
delete ppkt;