天天看點

安全傳輸平台項目——密鑰協商設計與實作--存資料庫-MFC項目建立

在學習安全傳輸平台項目總結了筆記,并分享出來。

10-安全傳輸平台項目-第08天(密鑰協商設計與實作--存資料庫-mfc項目建立)

一、複習

1、資料庫-SQL語句、事務、遊标回顧

2、資料庫-通路API、查詢語句API、非查詢語句API

3、資料庫-base64編碼

二、安全傳輸平台項目——密鑰協商設計與實作--存資料庫-MFC項目建立

1、密鑰協商存資料庫

icdbapi.h和keymng_dbop.h放入inc目錄下;keymng_dbop.c放入src目錄下。

>vi keymngserverop.c

1)增加頭檔案icdbapi.h和keymng_dbop.h;

2)MngServer_InitInfo函數增加-初始化資料庫連接配接池IC_DBApi_PoolInit函數;

3)MngServer_Agree函數增加-寫資料庫KeyMngsvr_DBOp_WriteSecKey函數;

4)MngServer_Agree函數增加-擷取一條資料庫連接配接池中的連接配接IC_DBApi_ConnGet函數;

5)MngServer_Agree函數增加-從資料庫中擷取 seckeyid的 KeyMngsvr_DBOp_GenKeyID函數;

6)MngServer_Agree函數增加-開啟事務的 IC_DBApi_BeginTran函數和關閉事務的iIC_DBApi_Rollback函數;

7)MngServer_Agree函數增加-釋放資料庫連接配接到連接配接池IC_DBApi_ConnFree函數;

#include <stdio.h>#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "keymngserverop.h"
#include "keymng_msg.h"
#include "keymnglog.h" 
#include "keymng_shmop.h"
#include "icdbapi.h"
#include "keymng_dbop.h"

//static int    seckeyid = 100;

int MngServer_InitInfo(MngServer_Info *svrInfo)
{
    int ret = 0;
    strcpy(svrInfo->serverId, "0001");
    strcpy(svrInfo->dbuse, "SECMNG");
    strcpy(svrInfo->dbpasswd, "SECMNG");
    strcpy(svrInfo->dbsid, "orcl");
    svrInfo->dbpoolnum = 8;    
    strcpy(svrInfo->serverip, "127.0.0.1");
    svrInfo->serverport = 8001;
    svrInfo->maxnode = 10;
    svrInfo->shmkey = 0x0001;
    svrInfo->shmhdl = 0;
    
    //建立/打開 共享記憶體
    ret = KeyMng_ShmInit(svrInfo->shmkey, svrInfo->maxnode, &svrInfo->shmhdl);
    if (ret != 0) {
        printf("---------伺服器建立/打開 共享記憶體失敗-----\n");
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "伺服器 KeyMng_ShmInit() err:%d", ret);
        return ret;
    }
    
    //初始化資料庫連接配接池
    ret = IC_DBApi_PoolInit(svrInfo->dbpoolnum, svrInfo->dbsid, svrInfo->dbuse, svrInfo->dbpasswd);
    if (ret != 0) {
        printf("---------伺服器初始化連接配接池失敗-----\n");
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "伺服器 IC_DBApi_PoolInit() err:%d", ret);
        return ret;
    }
    
    return 0;    
}

int MngServer_Agree(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen)
{
    int ret = 0;
    int i = 0;
    int keyid = -1;
    
    MsgKey_Res msgKey_Res;
    
    NodeSHMInfo nodeSHMInfo;
    
    ICDBHandle handle = NULL;
    
    // --結合 r1 r2 生成密鑰  ---> 成功、失敗 rv
    if (strcmp(svrInfo->serverId, msgkeyReq->serverId) != 0) {
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "用戶端通路了錯誤的伺服器");
        return -1;    
    }
    
    // 組織 應答結構體 res : rv r2 clientId serverId  seckeyid
    msgKey_Res.rv = 0;     //0 成功 1 失敗。
    strcpy(msgKey_Res.clientId, msgkeyReq->clientId); 
    strcpy(msgKey_Res.serverId, msgkeyReq->serverId); 
    
    // 生成随機數 r2
    for (i = 0; i < 64; i++) {
        msgKey_Res.r2[i] = 'a' + i;            
    }
    
    //擷取一條資料庫連接配接池中的連接配接
    ret = IC_DBApi_ConnGet(&handle, 0, 0);
    if (ret != 0) {
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "伺服器 IC_DBApi_ConnGet() err:%d", ret);    
        return ret;
    }
    
    //開啟事務
    IC_DBApi_BeginTran(handle);
    
    //從資料庫中擷取 seckeyid
    //msgKey_Res.seckeyid = seckeyid++;
    ret = KeyMngsvr_DBOp_GenKeyID(handle, &keyid);
    if (ret != 0) {
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "伺服器 KeyMngsvr_DBOp_GenKeyID() err:%d", ret);
        return ret;    
    }
    msgKey_Res.seckeyid = keyid;
    
    // 組織密鑰節點資訊結構體
    for (i = 0; i < 64; i++) {
        nodeSHMInfo.seckey[2*i] = msgkeyReq->r1[i];
        nodeSHMInfo.seckey[2*i+1] = msgKey_Res.r2[i];
    }
    nodeSHMInfo.status = 0;  //0-有效 1無效
    strcpy(nodeSHMInfo.clientId, msgkeyReq->clientId);
    strcpy(nodeSHMInfo.serverId, msgkeyReq->serverId);
    nodeSHMInfo.seckeyid = msgKey_Res.seckeyid;
    
    // --寫資料庫
    ret = KeyMngsvr_DBOp_WriteSecKey(handle, &nodeSHMInfo); 
    if (ret != 0) {
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "伺服器 KeyMngsvr_DBOp_WriteSecKey() err:%d", ret);    
    }
    
    // 關閉事務
    if (ret != 0) {
        iIC_DBApi_Rollback(handle);
        IC_DBApi_ConnFree(handle, 0);//釋放資料庫連接配接到連接配接池
        return -1;
    }
    else if(ret == 0)
    {
        IC_DBApi_Commit(handle);
        IC_DBApi_ConnFree(handle, 1);//釋放資料庫連接配接到連接配接池
    }
    
    // --寫入共享記憶體。
    ret = KeyMng_ShmWrite(svrInfo->shmhdl, svrInfo->maxnode, &nodeSHMInfo);
    if (ret != 0) {
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "伺服器 KeyMng_ShmWrite() err:%d", ret);
        return ret;    
    }
    
    // 編碼應答封包  傳出
    ret = MsgEncode(&msgKey_Res, ID_MsgKey_Res, outData, datalen);
    if (ret != 0) {
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "serverAgree MsgEncode() err:%d", ret);    
        return ret;
    }
    
    return 0;    
}


int MngServer_Check(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen)
{
    
    
    return 0;    
}
   keymngserverop.c  
>vi keymngserver.c      

1)增加頭檔案icdbapi.h;

2)main函數增加-釋放資料庫連接配接池 IC_DBApi_PoolFree()函數;

#include <stdio.h>#include <stdlib.h>#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
 
#include "poolsocket.h"  
#include "keymngserverop.h"
#include "keymng_msg.h"
#include "keymnglog.h"  
#include "icdbapi.h"

MngServer_Info serverInfo;

int flg = 1;

//注意定義宏的時候最後是一個整體,不能有空格!
#define CREATE_DAEMON if(fork()>0)exit(1);setsid();
 
void *start_routine(void * arg)
{
     int ret;
     int timeout = 3;
     int connfd = (int)arg;
     
     unsigned char *out = NULL;
     int outlen = 0;
     
     MsgKey_Req *pStruct_req = NULL;
     int iType = 0;
     
     unsigned char *res_outData = NULL;
     int res_outDataLen = 0;
     
     while (1) {
                 
        if (flg == 0) 
            break;    

        //伺服器端端接受封包
        ret = sckServer_rev(connfd, timeout, &out, &outlen); 
        if (ret == Sck_ErrPeerClosed) {
            // 檢測到 對端關閉,關閉本端。
            printf("----------------ErrPeerClosed 關閉伺服器\n");
            break;
        } else if (ret == Sck_ErrTimeOut) {
            if (out != NULL)  sck_FreeMem((void **)&out);
            continue;
        } else if (ret != 0) {
            printf("未知錯誤\n");
            break;
        }

        // 解碼用戶端 密鑰請求封包 ---> cmdType
        ret = MsgDecode(out, outlen, (void **)&pStruct_req, &iType);
        if (ret != 0) {
            KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "MsgDecode() err:%d", ret);    
            break;    
        }

        switch(pStruct_req->cmdType) {
            case KeyMng_NEWorUPDATE:
                ret = MngServer_Agree(&serverInfo, pStruct_req, &res_outData, &res_outDataLen);
            
            case KeyMng_Check:
                MngServer_Check(&serverInfo, pStruct_req, &res_outData, &res_outDataLen);
            /*    
            case 密鑰登出:
                mngServer_Agree();
                */
            default:
                break;
        }
        if (ret != 0) {        
            KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "MngServer_Agree() err:%d", ret);
            break;                
        }

         //伺服器端發送封包
        ret = sckServer_send(connfd, timeout, res_outData, res_outDataLen);
         if (ret == Sck_ErrPeerClosed) {
            // 檢測到 對端關閉,關閉本端。
            printf("---ErrPeerClosed \n");
            break;
        } else if (ret == Sck_ErrTimeOut) {
            printf("---伺服器檢測到本端發送資料 逾時 \n");
            if (out != NULL) sck_FreeMem((void **)&out);
            if (pStruct_req != NULL) MsgMemFree((void **)&pStruct_req, iType);
            if (res_outData != NULL) MsgMemFree((void **)&res_outData, 0);    
            continue;
        } else if (ret != 0) {
            printf("未知錯誤\n");
            break;
        }
    }
    
    if (out != NULL) sck_FreeMem((void **)&out);
    if (pStruct_req != NULL) MsgMemFree((void **)&pStruct_req, iType);
    if (res_outData != NULL) MsgMemFree((void **)&res_outData, 0);    
    
    sckServer_close(connfd);
    
     return NULL;
}

void catchSignal(int signum)
{
    flg = 0;
    printf(" catch signal %d, process is going to die.\n", signum);
    
    return ;
}

int main(void)
{
    int listenfd;
    int ret = 0;
    
    int timeout = 3;
    int connfd = -1;
    
    pthread_t pid;
    
    CREATE_DAEMON
    
    signal(SIGUSR1, catchSignal);
    
    // 伺服器資訊初始化。
    ret = MngServer_InitInfo(&serverInfo);
    if (ret != 0) {
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "MngServer_InitInfo() err:%d", ret);    
        return ret;
    }
    
    //伺服器端初始化連接配接
    ret = sckServer_init(serverInfo.serverport, &listenfd);
    if (ret != 0) {
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "sckServer_init() err:%d", ret);    
        return ret;
    }
    
    while (1) {    
        if (flg == 0) 
            break;
        
        ret = sckServer_accept(listenfd, timeout, &connfd);
        if (ret == Sck_ErrTimeOut){
            KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[2], ret, "---等待用戶端連接配接逾時---");
            continue;    
        } else if(ret != 0)  {
            KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "sckServer_accept() err:%d", ret);    
            return ret;
        }
        
        ret = pthread_create(&pid, NULL, start_routine, (void *)connfd);                    
    }
     
     //伺服器端環境釋放 
    sckServer_destroy();
    IC_DBApi_PoolFree();
    
    printf("伺服器 優雅退出。\n");

    return 0;    
}
   keymngserver.c  
>vi makefile      
.PHONY:clean allWORKDIR=.VPATH = ./srcCC=gcc
CFLGS= -Wall -g -I$(WORKDIR)/inc/
LIBFLAG = -L$(HOME)/lib


BIN = keymngclient  keymngserver 


all:$(BIN)

keymngclient:keymngclient.o  keymnglog.o  keymngclientop.o  myipc_shm.o keymng_shmop.o
    $(CC) $(LIBFLAG) -lpthread -litcastsocket -lmessagereal $^ -o $@ 
        
keymngserver:keymngserver.o  keymngserverop.o  keymnglog.o  myipc_shm.o  keymng_shmop.o keymng_dbop.o
    $(CC) $(LIBFLAG) $^ -o $@ -lpthread -litcastsocket -lmessagereal -lclntsh  -licdbapi
 
#testdbapi:testdbapi.o  
#    $(CC) $(LIBFLAG) $^ -o $@ -lpthread  -lclntsh  -licdbapi
        
%.o:%.c
    $(CC) $(CFLGS) -c $< -o $@    

clean:
    rm -f *.o $(BIN)
   makefile  
>make
>./keymngserver      
安全傳輸平台項目——密鑰協商設計與實作--存資料庫-MFC項目建立

打開另一個終端,切換到該目錄下,執行>./keymngclient

安全傳輸平台項目——密鑰協商設計與實作--存資料庫-MFC項目建立

連續執行3次後,打開SQL Developer檢視表中資料:

>SECKYEINFO表:

安全傳輸平台項目——密鑰協商設計與實作--存資料庫-MFC項目建立

>KEYSN表:

安全傳輸平台項目——密鑰協商設計與實作--存資料庫-MFC項目建立

2、表外鍵限制導緻的插入時間錯誤

3、密鑰登出流程分析

4、4大基礎元件源碼

5、資料庫連接配接池錯誤說明

6、配置ODBC驅動

7、ODBC驅動錯誤說明

8、界面架構思想

9、MFC空項目建立

10、處理源碼中CUR圖示對應錯誤

11、添加消息宏定義