zoukankan      html  css  js  c++  java
  • 安全传输平台项目——密钥协商服务器-密钥协商客户端

    在学习安全传输平台项目总结了笔记,并分享出来。有问题请及时联系博主:Alliswell_WP,转载请注明出处。

    10-安全传输平台项目-第05天(密钥协商服务器-密钥协商客户端)

    目录:
    一、复习
    二、安全传输平台项目——密钥协商服务器-密钥协商客户端
    1、密钥协商-物理组件集成
    2、密钥协商-日志的使用
    3、密钥协商客户端-模块划分
    4、密钥协商客户端-框架实现
    5、密钥协商客户端-Agree函数框架
    6、密钥协商客户端-Agree函数实现
    7、密钥协商客户端-Agree函数内存释放
    8、密钥协商服务器-框架梳理
    9、密钥协商服务器-业务逻辑实现
    10、密钥协商服务器-Agree功能实现
    11、总结

    一、复习

    1、线程传参
    2、共享内存

    二、安全传输平台项目——密钥协商服务器-密钥协商客户端

    》密钥协商业务逻辑图

    1、密钥协商-物理组件集成

    》创建相应的文件夹及文件准备

    >mkdir secmng
    >cd secmng
    >mkdir inc
    >mkdir lib
    >mkdir src

    通过远程软件,将库文件:libitcastsocket.so和libmessagereal.so拷贝到新创建的lib目录下;

    把(keymnglog.cmyipc_shm.c)2个文件放入到src目录下,把(keymng_msg.h—统一报文编码解码,对应lib库libmessagereal.so、keymnglog.h—日志,对应inc的keymnglog.c、myipc_shm.h—统一共享内存,对应inc的myipc_shm.c、poolsocket.h—统一通信,对应lib库libitcastsocket.so)4个文件放入到inc目录下。

    >vi keymnglog.c

    #define  _CRT_SECURE_NO_WARNINGS 
    
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <stdarg.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    #include "keymnglog.h"
    
    #define ITCAST_DEBUG_FILE_    "keymngclient.log"
    #define ITCAST_MAX_STRING_LEN         10240
    
    //Level类别
    #define IC_NO_LOG_LEVEL            0
    #define IC_DEBUG_LEVEL            1
    #define IC_INFO_LEVEL            2
    #define IC_WARNING_LEVEL        3
    #define IC_ERROR_LEVEL            4
    
    int  KeyMngLevel[5] = {IC_NO_LOG_LEVEL, IC_DEBUG_LEVEL, IC_INFO_LEVEL, IC_WARNING_LEVEL, IC_ERROR_LEVEL};
    
    //Level的名称
    char ICLevelName[5][10] = {"NOLOG", "DEBUG", "INFO", "WARNING", "ERROR"};
    
    static int ITCAST_Error_GetCurTime(char* strTime)
    {
        struct tm*        tmTime = NULL;
        size_t            timeLen = 0;
        time_t            tTime = 0;    
        
        tTime = time(NULL);
        tmTime = localtime(&tTime);
        //timeLen = strftime(strTime, 33, "%Y(Y)%m(M)%d(D)%H(H)%M(M)%S(S)", tmTime);
        timeLen = strftime(strTime, 33, "%Y.%m.%d %H:%M:%S", tmTime);
        
        return timeLen;
    }
    
    static int ITCAST_Error_OpenFile(int* pf)
    {
        char    fileName[1024];
        
        memset(fileName, 0, sizeof(fileName));
    #ifdef WIN32
        sprintf(fileName, "c:\itcast\%s",ITCAST_DEBUG_FILE_);
    #else
        sprintf(fileName, "%s/log/%s", getenv("HOME"), ITCAST_DEBUG_FILE_);
    #endif
        
        *pf = open(fileName, O_WRONLY|O_CREAT|O_APPEND, 0666);
        if(*pf < 0)
        {
            return -1;
        }
        
        return 0;
    }
    
    static void ITCAST_Error_Core(const char *file, int line, int level, int status, const char *fmt, va_list args)
    {
        char str[ITCAST_MAX_STRING_LEN];
        int     strLen = 0;
        char tmpStr[64];
        int     tmpStrLen = 0;
        int  pf = 0;
        
        //初始化
        memset(str, 0, ITCAST_MAX_STRING_LEN);
        memset(tmpStr, 0, 64);
        
        //加入LOG时间
        tmpStrLen = ITCAST_Error_GetCurTime(tmpStr);
        tmpStrLen = sprintf(str, "[%s] ", tmpStr);
        strLen = tmpStrLen;
    
        //加入LOG等级
        tmpStrLen = sprintf(str+strLen, "[%s] ", ICLevelName[level]);
        strLen += tmpStrLen;
        
        //加入LOG状态
        if (status != 0) 
        {
            tmpStrLen = sprintf(str+strLen, "[ERRNO is %d] ", status);
        }
        else
        {
            tmpStrLen = sprintf(str+strLen, "[SUCCESS] ");
        }
        strLen += tmpStrLen;
    
        //加入LOG信息
        tmpStrLen = vsprintf(str+strLen, fmt, args);
        strLen += tmpStrLen;
    
        //加入LOG发生文件
        tmpStrLen = sprintf(str+strLen, " [%s]", file);
        strLen += tmpStrLen;
    
        //加入LOG发生行数
        tmpStrLen = sprintf(str+strLen, " [%d]
    ", line);
        strLen += tmpStrLen;
        
        //打开LOG文件
        if(ITCAST_Error_OpenFile(&pf))
        {
            return ;
        }
        
        //写入LOG文件
        write(pf, str, strLen);
        //IC_Log_Error_WriteFile(str);
        
        //关闭文件
        close(pf);
        
        return ;
    }
    
    
    void KeyMng_Log(const char *file, int line, int level, int status, const char *fmt, ...)
    {
        va_list args;
        
        //判断是否需要写LOG
    //    if(level!=IC_DEBUG_LEVEL && level!=IC_INFO_LEVEL && level!=IC_WARNING_LEVEL && level!=IC_ERROR_LEVEL)
        if(level == IC_NO_LOG_LEVEL)
        {
            return ;
        }
        
        //调用核心的写LOG函数
        va_start(args, fmt);
        ITCAST_Error_Core(file, line, level, status, fmt, args);
        va_end(args);
        
        return ;
    }
    keymnglog.c

    >vi myipc_shm.c

    #define    _OS_LINUX_
    
    #if defined _OS_LINUX_
    #include <stdio.h>
    #include <errno.h>
    #include <unistd.h>
    #include <memory.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <sys/sem.h>
    #include <sys/msg.h>
    #include "myipc_shm.h" 
    
    #endif
    
    int shmflag = 0;
    int shmkey;
    
    
    //创建共享内存 若共享内存不存在,则创建 若存在使用原来的
    int IPC_CreatShm(int key, int shmsize, int *shmhdl)
    {
        int        tmpshmhdl = 0;
        int     ret = 0;
         //    创建共享内存 
         //    若共享内存不存在则创建 
         //    若共享内存已存在使用原来的
        tmpshmhdl = shmget(key, shmsize, IPC_CREAT|0666);
        if (tmpshmhdl == -1)            //创建失败
        {
            ret = MYIPC_ParamErr;
            printf("func shmget() err :%d ", ret);
            return ret;
        }
        *shmhdl = tmpshmhdl;
        return ret;
    }
    
    //打开共享内存 若共享内存不存在,返回错误
    //参数 无意义 可填写0
    int IPC_OpenShm(int key, int shmsize, int *shmhdl)
    {
        int        tmpshmhdl = 0;
        int     ret = 0;
         //    创建共享内存 
         //    若共享内存不存在则创建 
         //    若共享内存已存在使用原来的
        tmpshmhdl = shmget(key, 0, 0);
        if (tmpshmhdl == -1)            //打开失败
        {
            ret = MYIPC_NotEXISTErr;
            //printf("func shmget() err :%d ", ret);
            return ret;
        }
        *shmhdl = tmpshmhdl;
        return ret;
        
    }
    
    /***********************************************************************
      功能描述:    创建共享内存
      参数说明:    shmname  [in]  是共享内存名,系统中唯一标志
                    shmsize  [in]  是要创建的共享内存的大小;
                    shmhdl   [out] 共享内存的句柄.
      返回值:      返回0函数执行成功;非0返回错误码
    ************************************************************************/
    int IPC_CreatShmBySeedName(const char *shmseedfile, int shmsize, int *shmhdl)
    {
        if(shmflag == 0)            //判断接口中共享内存key是否已经存在
        {
            shmkey = ftok(shmseedfile, 'c');
            if (shmkey == -1)
            {
                perror("ftok");
                return -1;
            }
                
            shmflag = 1;
        }
        
        //创建共享内存
        *shmhdl = shmget(shmkey,shmsize,IPC_CREAT|0666);
        if (*shmhdl == -1)            //创建失败
            return -2;
        return 0;
    
    }
    /***********************************************************************
      功能描述:    关联共享内存
      参数说明:    shmhdl    [in]  共享的句柄
                    mapaddr [out] 共享内存首地址
      返回值:      返回0函数执行成功;非0返回错误码
    ************************************************************************/
    int
    IPC_MapShm(int  shmhdl, void **mapaddr)
    {
        void *tempptr = NULL;
    
        //连接共享内存
        tempptr = (void *)shmat(shmhdl,0,SHM_RND);
        if ((int)tempptr == -1)        //共享内存连接失败
            return -1;
        *mapaddr = tempptr;            //导出共享内存首指针
    
        return 0;
    }
    /***********************************************************************
      功能描述:    取消共享内存关联
      参数说明:    unmapaddr   [in] 共享内存首地址
      返回值:      返回0函数执行成功;非0返回错误码
    ************************************************************************/
    int IPC_UnMapShm(void *unmapaddr)
    {
        int  rv;
        //取消连接共享内存 
        rv = shmdt((char *)unmapaddr);
        if (rv == -1)            //取消连接失败
            return -1;
    
        return 0;
    }
    /***********************************************************************
      功能描述:    删除共享内存
      参数说明:    shmhdl    [in]  共享的句柄
      返回值:      返回0函数执行成功;非0返回错误码
    ************************************************************************/
    int IPC_DelShm(int shmhdl)
    {
        int  rv;
        //删除共享内存
        rv = shmctl(shmhdl,IPC_RMID,NULL);
        if(rv < 0)                //删除共享内存失败
            return -1;
            
        return 0;
    }
    myipc_shm.c

    >vi keymng_msg.h

    #ifndef _KEYMNG_MSG_H_
    #define _KEYMNG_MSG_H_
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    #define        KeyMng_ParamErr            200        //输入参数失败
    #define        KeyMng_TypeErr            201        //输入类型失败
    #define        KeyMng_MallocErr        202        //分配内存失败
    
    #define        KeyMng_NEWorUPDATE        1        //1 密钥协商 
    #define        KeyMng_Check            2        //2 密钥校验
    #define        KeyMng_Revoke            3        //3 密钥注销
                     
    #define  ID_MsgKey_Teacher  80
    typedef struct _Teacher
    {
        char name[64];
        int age;
        char *p;
        int plen;
    }Teacher;
    
    
    //密钥请求报文 --- 结构体
    #define  ID_MsgKey_Req  60
    typedef struct _MsgKey_Req
    {
        //1 密钥协商      //2 密钥校验;     //3 密钥注销
        int                cmdType;        //报文命令码 
        char            clientId[12];    //客户端编号
        char            AuthCode[16];    //认证码
        char            serverId[12];    //服务器端I编号 
        char            r1[64];        //客户端随机数
        
    }MsgKey_Req;
    
    
    //密钥应答报文 --- 结构体
    #define  ID_MsgKey_Res  61
    typedef struct  _MsgKey_Res
    {
        int                    rv;                //返回值
        char                clientId[12];    //客户端编号
        char                serverId[12];    //服务器编号
        unsigned char        r2[64];            //服务器端随机数
        int                    seckeyid;        //对称密钥编号 //modfy 2015.07.20
    }MsgKey_Res;
    
    
    /*
     pstruct :    输入的报文数据 ; (指向相应结构体的指针) 
     type :        输入的类型标识(函数内部通过type 得到 pstruct 所指向的报文类型)
     poutData:    输出的编码后的报文 ; 
     outlen :    输出的数据长度;
    */
    
    int MsgEncode(
        void            *pStruct , /*in*/
        int                type,
        unsigned char    **outData, /*out*/
        int                *outLen );
    
    /*
     inData        : 输入的编码后的数据;
     inLen        : 输入的数据长度 ;
     pstruct    : 输出的解码后的数据; (其空间是在内部开辟的,也需要用内部定义的free函数进行释放)
     type        : 结构的类型标识(返回类型标识,使得调用者通过flag进行判断,将pstruct 转换为相应的结构)
    */
    
    int MsgDecode( 
        unsigned char *inData,/*in*/
        int           inLen,
        void          **pStruct /*out*/,
        int           *type /*out*/);
    
    
    /*
    释放 MsgEncode( )函数中的outData; 方法:MsgMemFree((void **)outData, 0); 
    释放MsgDecode( )函数中的pstruct结构体,MsgMemFree((void **)outData, type);
    type : 输入参数,便于函数判断调用哪个结构体的free函数
    */ 
    
    int MsgMemFree(void **point, int type);
    
    #ifdef __cplusplus
    }
    #endif
    
    
    #endif
    keymng_msg.h

    >vi keymnglog.h

    //keymnglog.h 日志头文件
    
    
    
    // keymnglog.h
    
    #ifndef _KEYMNG_LOG_H_
    #define _KEYMNG_LOG_H_
    
    /************************************************************************/
    /* 
    const char *file:文件名称
    int line:文件行号
    int level:错误级别
            0 -- 没有日志
            1 -- debug级别
            2 -- info级别
            3 -- warning级别
            4 -- err级别
    int status:错误码
    const char *fmt:可变参数
    */
    /************************************************************************/
    //实际使用的Level
    extern int  KeyMngLevel[5];
    
    void KeyMng_Log(const char *file, int line, int level, int status, const char *fmt, ...);
    
    #endif
    keymnglog.h

    >vi myipc_shm.h

    // myipc_shm.h
    #ifndef _WBM_MY_SHM_H_
    #define _WBM_MY_SHM_H_
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #ifdef __cplusplus 
    extern "C" {
    #endif
    
    //共享内存错误码
    #define        MYIPC_OK                0        //正确
    #define        MYIPC_ParamErr            301        //输入参数失败
    #define        MYIPC_NotEXISTErr        302        //共享内存不存在错误
    #define        MYIPC_CreateErr            303        //创建共享内存错误
    
    //创建共享内存 若共享内存不存在,则创建
    int IPC_CreatShm(int key, int shmsize, int *shmhdl);
    
    //打开共享内存 若共享内存不存在,返回错误
    int IPC_OpenShm(int key, int shmsize, int *shmhdl);
    
    /***********************************************************************
      功能描述:    关联共享内存
      参数说明:    shmhdl    [in]  共享的句柄
                    mapaddr [out] 共享内存首地址
      返回值:      返回0函数执行成功;非0返回错误码
    ************************************************************************/
    int IPC_MapShm(int shmhdl, void **mapaddr);
    
    /***********************************************************************
      功能描述:    取消共享内存关联
      参数说明:    unmapaddr   [in] 共享内存首地址
      返回值:      返回0函数执行成功;非0返回错误码
    ************************************************************************/
    int IPC_UnMapShm(void *unmapaddr);
    
    /***********************************************************************
      功能描述:    删除共享内存
      参数说明:    shmhdl    [in]  共享的句柄
      返回值:      返回0函数执行成功;非0返回错误码
    ************************************************************************/
    int IPC_DelShm(int shmhdl);
    
    /***********************************************************************
      功能描述:    创建共享内存 通过种子文件
      参数说明:    shmname  [in]  是共享内存名,系统中唯一标志
                    shmsize  [in]  是要创建的共享内存的大小;
                    shmhdl   [out] 共享内存的句柄.
      返回值:      返回0函数执行成功;非0返回错误码
    ************************************************************************/
    int IPC_CreatShmBySeedName(const char *shmname, int shmsize, int *shmhdl);
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    myipc_shm.h

    >vi poolsocket.h

    #ifndef _poolsocket_H_
    #define _poolsocket_H_
    
    #ifdef __cplusplus
    extern 'C'
    {
    #endif
    
    //错误码定义  
    #define Sck_Ok                 0
    #define Sck_BaseErr           3000
    
    #define Sck_ErrParam                    (Sck_BaseErr+1)
    #define Sck_ErrTimeOut                    (Sck_BaseErr+2)
    #define Sck_ErrPeerClosed               (Sck_BaseErr+3)
    #define Sck_ErrMalloc                       (Sck_BaseErr+4)
    
    #define Sck_Err_Pool_CreateConn                (Sck_BaseErr+20)  //创建连接池 (没有达到最大连接数)
    #define Sck_Err_Pool_terminated                (Sck_BaseErr+21) //已终止
    #define Sck_Err_Pool_GetConn_ValidIsZero    (Sck_BaseErr+22) //有效连接数是零
    #define Sck_Err_Pool_HaveExist                (Sck_BaseErr+22) //连接已经在池中
    #define Sck_Err_Pool_ValidBounds            (Sck_BaseErr+22) //有效连接数目超过了最大连接数
    
    
    //客户端 初始化
    int sckClient_init();
    
    //客户端 连接服务器
    int sckClient_connect(char *ip, int port, int connecttime, int *connfd);
    
    //客户端 关闭和服务端的连接
    int sckClient_closeconn(int connfd);
    
    //客户端 发送报文
    int sckClient_send(int connfd, int sendtime, unsigned char *data, int datalen);
    
    //客户端 接受报文
    int sckClient_rev(int connfd, int revtime, unsigned char **out, int *outlen); //1
    
    //客户端 释放
    int sckClient_destroy();
    
    
    
    //释放内存
    int sck_FreeMem(void **buf);
    
    
    
    typedef struct _SCKClitPoolParam
    {
        char     serverip[64];
        int     serverport;
        int     bounds; //池容量
        int     connecttime;
        int     sendtime;
        int     revtime;
    }SCKClitPoolParam;
    
    
    //客户端 socket池初始化
    int sckCltPool_init(void **handle, SCKClitPoolParam *param);  //ip port 数量 
    
    //客户端 socket池 获取一条连接 
    int sckCltPool_getConnet(void *handle, int *connfd);
    
    //客户端 socket池 发送数据 
    int sckCltPool_send(void *handle, int connfd, unsigned char *data, int datalen);
    
    //客户端 socket池 接受数据
    int sckCltPool_rev(void *handle, int connfd, unsigned char **out, int *outlen); //1
    
    //客户端 socket池 把连接放回 socket池中 
    int sckCltPool_putConnet(void *handle, int connfd, int validFlag); //0正常 1
    
    //客户端 socket池 销毁连接
    int sckCltPool_destroy(void *handle);
    
    
    //服务器端初始化
    int sckServer_init(int port, int *listenfd);
    
    int sckServer_accept(int listenfd, int timeout, int *connfd);
    
    //服务器端发送报文
    int sckServer_send(int connfd, int timeout, unsigned char *data, int datalen);
    
    //服务器端端接受报文
    int sckServer_rev(int  connfd, int timeout, unsigned char **out, int *outlen); //1
    
    int sckServer_close(int connfd);
    
    //服务器端环境释放 
    int sckServer_destroy();
    
    
    #ifdef __cpluspluse
    }
    #endif
    
    
    #endif
    poolsocket.h

    2、密钥协商-日志的使用

    >cd src
    >touch keymngclient.c
    >touch keymngserver.c
    >vi keymngclient.c

    #include "keymnglog.h"
    
    int main(void)
    {
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[0], 0, "%s", "00000000000000");
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[1], 1, "%s", "11111111111111");
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[2], 2, "%s", "22222222222222");
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[3], 3, "%s", "33333333333333");
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], 4, "%s", "44444444444444");
        
        return 0;    
    }
    keymngclient.c

    >gcc keymngclient.c keymnglog.c -o keymngclient -I ../inc
    >./keymngclient

    打开另一个终端,然后在家目录的log目录下查看日志

    注意:0的时候没有日志,所以查看的时候只有4行。

    3、密钥协商客户端-模块划分

    》密钥协商客户端:        keymngclient.c
        显示菜单。
        接收用户选择。  num。
        客户端信息初始化。
        switch(num) {
            case 1协商:
                密钥协商。 建立连接、封装req结构体、编码、发送、接收、解码、生成密钥、写共享内存。
                _Agree();

            case 2校验:
                密钥校验。 建立连接、封装req结构体、编码、发送、接收、解码、展示结果给用户。
                _Check();    

            case 3查看:
                密钥查看。 建立连接、封装req结构体、编码、发送、接收、解码、展示密钥相关信息给用户。
                _View();
            。。。。
        }

        将结果展示给用户。

    》模块划分:
        业务逻辑:
            keymngclient.c
        业务功能:
            keymngclientop.c            -->           keymngclientop.h
            实现 客户端信息初始化。                客户端信息初始化声明。             
            实现 客户端密钥协商。                。。。。
            实现 客户端密钥校验。

            struct clientInfo { serverIp, serverPort, clientID, serverID, Autocode, shmkey, shmid, maxnode }

      int keymng_initInfo(struct clientInfo *pInfo);传出参数

            int keymng_Agree(struct clientInfo *pInfo)
            int keymng_Check(struct clientInfo *pInfo);
            int keymng_Revoke(struct clientInfo *pInfo);

    ====================================================================
    》密钥协商服务器:
        keymngserverop.c         keymngserverop.h        功能实现
        实现 服务器信息初始化。        服务器信息初始化声明。             
        实现 服务器密钥协商。        。。。。
        实现 服务器密钥校验。   
        实现 服务器密钥注销。

    4、密钥协商客户端-框架实现

    》文件准备:

    // keymngclientop.h
    
    #ifndef _KEYMNG_CLIENTOP_H_
    #define _KEYMNG_CLIENTOP_H_
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    #define        MngClt_OK                0            //正确
    #define        MngClt_ParamErr            301            //输入参数失败
    #define        MngClt_NoNetPointErr    302            //共享内存中,没有找到网点信息
    #define        MngClt_NodeMaxCount        303            //共享内存中,超过最大网点
    
    typedef struct _MngClient_Info
    {
        char            clientId[12];    //客户端编号
        char            AuthCode[16];    //认证码
        char            serverId[12];    //服务器端编号
        
        char            serverip[32];
        int             serverport;
        
        int                maxnode;         //最大网点数 客户端默认1个
        int             shmkey;             //共享内存keyid 创建共享内存时使用     
        int             shmhdl;         //共享内存句柄    
    }MngClient_Info;
    
    
    //初始化客户端 全局变量
    int MngClient_InitInfo(MngClient_Info *pCltInfo);
    
    int MngClient_Quit(MngClient_Info *pCltInfo);
    
    int MngClient_Agree(MngClient_Info *pCltInfo);
    
    int MngClient_Check(MngClient_Info *pCltInfo);
    
    int MngClient_Revoke(MngClient_Info *pCltInfo);
    
    int MngClient_view(MngClient_Info *pCltInfo);
    
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif
    keymngclientop.h

    将keymngclientop.h放入ins目录下,然后在src新建keymngclientop.c,进行开发

    >touch keymngclientop.c

    >vi keymngclientop.c

    #include <stdio.h>
    #include <stdlib.h>
    #include "keymngclientop.h"
    
    int MngClient_InitInfo(MngClient_Info *pCltInfo)
    {
        strcpy(pCltInfo->clientId, "1111");
        strcpy(pCltInfo->AuthCode, "1111");
        strcpy(pCltInfo->serverId, "0001");
        strcpy(pCltInfo->serverip, "127.0.0.1");
        pCltInfo->serverport = 8001;
        
        pCltInfo->maxnode = 1;
        pCltInfo->shmkey = 0x0011;
        pCltInfo->shmhdl = 0;    
        
        return 0;
    }
    
    int MngClient_Agree(MngClient_Info *pCltInfo)
    {
        
        return 0;
    }
    keymngclientop.c

    5、密钥协商客户端-Agree函数框架

    >keymngclient.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include "keymngclientop.h"
    #include "keymng_msg.h"
    #include "keymnglog.h"
    
    int main111(void)
    {
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[0], 0, "%s", "00000000000000");
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[1], 1, "%s", "11111111111111");
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[2], 2, "%s", "22222222222222");
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[3], 3, "%s", "33333333333333");
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], 4, "%s", "44444444444444");
        
        return 0;    
    }
    
    int Usage()
    {
        int nSel = -1;
        
        system("clear");    
        printf("
      /*************************************************************/");
        printf("
      /*************************************************************/");
        printf("
      /*     1.密钥协商                                            */");
        printf("
      /*     2.密钥校验                                            */");
        printf("
      /*     3.密钥注销                                            */");
        printf("
      /*     4.密钥查看                                            */");
        printf("
      /*     0.退出系统                                            */");
        printf("
      /*************************************************************/");
        printf("
      /*************************************************************/");
        printf("
    
      选择:");
        scanf("%d", &nSel);
        while(getchar() != '
    '); //把应用程序io缓冲器的所有的数据 都读走,避免影响下一次 输入
        
        return nSel;
    }
    
    int main()
    {
        int                 ret = 0;
        int                 nSel = 0;
        
        MngClient_Info        mngClientInfo;
        memset(&mngClientInfo, 0, sizeof(MngClient_Info));
    
        // 初始化客户端结构体信息
        ret = MngClient_InitInfo(&mngClientInfo);
        if (ret != 0)
        {
            printf("func MngClient_InitInfo() err:%d 
     ", ret);
            KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func MngClient_InitInfo() err:%d", ret);
        }
        
        while (1)
        {
            // 显示菜单  接收用户选择
            nSel = Usage();
            
            switch (nSel)
            {
            case KeyMng_NEWorUPDATE:    
                //密钥协商
                ret =  MngClient_Agree(&mngClientInfo);
                break;
            case KeyMng_Check:    
                //ret = MngClient_Check(&mngClientInfo);
                break;
            case KeyMng_Revoke:    
                //密钥注销
                break;
            case 0:    
                //退出
                return 0;
                
            default :
                printf("选项不支持
    ");
                break;
            }
            
            // 结果展示给用户。
            if (ret)
            {
                printf("
    !!!!!!!!!!!!!!!!!!!!ERROR!!!!!!!!!!!!!!!!!!!!");
                printf("
    错误码是:%x
    ", ret);
            }
            else
            {
                printf("
    !!!!!!!!!!!!!!!!!!!SUCCESS!!!!!!!!!!!!!!!!!!!!
    ");
            }    
            getchar();    
        }
        
        return 0;
    }
    keymngclient.c

    >keymngclientop.c

    int MngClient_Agree(MngClient_Info *pCltInfo)
    {
        //组织密钥请求结构体 req
    
        //编码密钥请求结构体 req --> TLV
    
        //初始化连接 --> listenfd
    
        //建立连接 --> connfd
    
        //发送请求报文 --> TLV send
    
        //接收应答报文 --> 服务器TLV res
    
        //解析应答报文 --> TLV --> Struct --> rv / r2
    
        //生成密钥 --> r1 r2 算法 --> 密钥
    
        //写共享内存。--> 存储
       
        return 0;
    }

    >vi keymngclientop.c

    #include <stdio.h>
    #include <stdlib.h>
    #include "keymngclientop.h"
    
    int MngClient_InitInfo(MngClient_Info *pCltInfo)
    {
        strcpy(pCltInfo->clientId, "1111");
        strcpy(pCltInfo->AuthCode, "1111");
        strcpy(pCltInfo->serverId, "0001");
        strcpy(pCltInfo->serverip, "127.0.0.1");
        pCltInfo->serverport = 8001;
        
        pCltInfo->maxnode = 1;
        pCltInfo->shmkey = 0x0011;
        pCltInfo->shmhdl = 0;    
        
        return 0;
    }
    
    int MngClient_Agree(MngClient_Info *pCltInfo)
    {
        //组织密钥请求结构体
    
        //编码密钥请求结构体
    
        //初始化连接
    
        //建立连接
    
        //发送请求报文
    
        //接收应答报文
    
        //解析应答报文
    
        //生成密钥
    
        //写共享内存。
        
        
        return 0;
    }
    keymngclientop.c

    6、密钥协商客户端-Agree函数实现

    >keymngclient.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include "keymngclientop.h"
    #include "keymng_msg.h"
    #include "keymnglog.h"
    
    int main111(void)
    {
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[0], 0, "%s", "00000000000000");
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[1], 1, "%s", "11111111111111");
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[2], 2, "%s", "22222222222222");
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[3], 3, "%s", "33333333333333");
        KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], 4, "%s", "44444444444444");
        
        return 0;    
    }
    
    int Usage()
    {
        int nSel = -1;
        
        system("clear");    
        printf("
      /*************************************************************/");
        printf("
      /*************************************************************/");
        printf("
      /*     1.密钥协商                                            */");
        printf("
      /*     2.密钥校验                                            */");
        printf("
      /*     3.密钥注销                                            */");
        printf("
      /*     4.密钥查看                                            */");
        printf("
      /*     0.退出系统                                            */");
        printf("
      /*************************************************************/");
        printf("
      /*************************************************************/");
        printf("
    
      选择:");
        scanf("%d", &nSel);
        while(getchar() != '
    '); //把应用程序io缓冲器的所有的数据 都读走,避免影响下一次 输入
        
        return nSel;
    }
    
    int main()
    {
        int                 ret = 0;
        int                 nSel = 0;
        
        MngClient_Info        mngClientInfo;
        memset(&mngClientInfo, 0, sizeof(MngClient_Info));
    
        // 初始化客户端结构体信息
        ret = MngClient_InitInfo(&mngClientInfo);
        if (ret != 0)
        {
            printf("func MngClient_InitInfo() err:%d 
     ", ret);
            KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func MngClient_InitInfo() err:%d", ret);
        }
        
        while (1)
        {
            // 显示菜单  接收用户选择
            nSel = Usage();
            
            switch (nSel)
            {
            case KeyMng_NEWorUPDATE:    
                //密钥协商
                ret =  MngClient_Agree(&mngClientInfo);
                break;
            case KeyMng_Check:    
                //ret = MngClient_Check(&mngClientInfo);
                break;
            case KeyMng_Revoke:    
                //密钥注销
                break;
            case 0:    
                //退出
                return 0;
                
            default :
                printf("选项不支持
    ");
                break;
            }
            
            // 结果展示给用户。
            if (ret)
            {
                printf("
    !!!!!!!!!!!!!!!!!!!!ERROR!!!!!!!!!!!!!!!!!!!!");
                printf("
    错误码是:%x
    ", ret);
            }
            else
            {
                printf("
    !!!!!!!!!!!!!!!!!!!SUCCESS!!!!!!!!!!!!!!!!!!!!
    ");
            }    
            getchar();    
        }
        
        return 0;
    }
    keymngclient.c

    >keymngclientop.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    
    #include "keymnglog.h"
    #include "poolsocket.h"
    #include "keymng_msg.h"
    #include "keymngclientop.h"
    
    int MngClient_InitInfo(MngClient_Info *pCltInfo)
    {
        strcpy(pCltInfo->clientId, "1111");
        strcpy(pCltInfo->AuthCode, "1111");
        strcpy(pCltInfo->serverId, "0001");
        strcpy(pCltInfo->serverip, "127.0.0.1");
        pCltInfo->serverport = 8001;
        
        pCltInfo->maxnode = 1;
        pCltInfo->shmkey = 0x0011;
        pCltInfo->shmhdl = 0;    
        
        return 0;
    }
    
    int MngClient_Agree(MngClient_Info *pCltInfo)
    {
        int i = 0; 
        int ret = 0; 
        int time = 3;
        
        int connfd = -1;
        
        // 存放编码 TLV 完成的 req
        unsigned char    *msgKey_Req_Data = NULL;   
        int             msgKey_Req_DataLen = 0;
        
        // 存放编码 TLV 完成的 res
        unsigned char    *msgKey_Res_Data = NULL;
        int             msgKey_Res_DataLen = 0;
        
        MsgKey_Res         *pStruct_Res = NULL;
        int             iType = 0;
    
        // 初始化密钥请求结构体
        MsgKey_Req msgKey_req;
        msgKey_req.cmdType = KeyMng_NEWorUPDATE;
        strcpy(msgKey_req.clientId, pCltInfo->clientId);
        strcpy(msgKey_req.AuthCode, pCltInfo->AuthCode);
        strcpy(msgKey_req.serverId, pCltInfo->serverId);    
        
        // 产生随机数         abcdefg
        for (i = 0; i < 64; i++) {
            msgKey_req.r1[i] = 'a' + i;    
        }
        
        // 编码密钥请求 结构体 req
        ret = MsgEncode(&msgKey_req, ID_MsgKey_Req, &msgKey_Req_Data, &msgKey_Req_DataLen);
        if (ret != 0) {        
            KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func MsgEncode() err:%d", ret);
            return 0;    
        }
        
        // 初始化建立连接函数
        ret = sckClient_init();
        if (ret != 0) {
            KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func sckClient_init() err:%d", ret);
            return 0;    
        }
            
        // 创建连接。
        ret = sckClient_connect(pCltInfo->serverip, pCltInfo->serverport, time, &connfd);
        if (ret != 0) {
            KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func sckClient_connect() err:%d", ret);
            return 0;    
        }
            
        // 发送数据
        ret = sckClient_send(connfd, time, msgKey_Req_Data, msgKey_Req_DataLen);
        if (ret != 0) {
            KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func sckClient_send() err:%d", ret);
            return 0;    
        }
            
        // ---- 等待服务器回发数据
        
        // 接收数据
        ret = sckClient_rev(connfd, time, &msgKey_Res_Data, &msgKey_Res_DataLen);
        if (ret != 0) {
            KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func sckClient_rev() err:%d", ret);
            return 0;    
        }    
        
        // 解码密钥应答 结构体 res ---> rv r2
        ret = MsgDecode(msgKey_Res_Data, msgKey_Res_DataLen, (void **)&pStruct_Res, &iType);
        if (ret != 0) {
            KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func MsgDecode() err:%d", ret);
            return 0;    
        }    
        
        if (pStruct_Res->rv != 0) {
            ret    = -1;
            return 0;
        } else if (pStruct_Res->rv == 0) {
            ret = 0;
            printf("---当前生成的密钥编号为:%d
    ", pStruct_Res->seckeyid);    
            return 0;
        }
        
        // --利用 r1 r2 生成密钥
        
        // --写入共享内存。
        
    
        
        return ret;    
    }
    keymngclientop.c

    注意:生成密钥 --> r1 r2 算法 --> 密钥 和 写共享内存。--> 存储 暂不实现。

    7、密钥协商客户端-Agree函数内存释放

    >free——MsgMemFree

    >keymngclientop.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    
    #include "keymnglog.h"
    #include "poolsocket.h"
    #include "keymng_msg.h"
    #include "keymngclientop.h"
    
    int MngClient_InitInfo(MngClient_Info *pCltInfo)
    {
        strcpy(pCltInfo->clientId, "1111");
        strcpy(pCltInfo->AuthCode, "1111");
        strcpy(pCltInfo->serverId, "0001");
        strcpy(pCltInfo->serverip, "127.0.0.1");
        pCltInfo->serverport = 8001;
        
        pCltInfo->maxnode = 1;
        pCltInfo->shmkey = 0x0011;
        pCltInfo->shmhdl = 0;    
        
        return 0;
    }
    
    int MngClient_Agree(MngClient_Info *pCltInfo)
    {
        int i = 0; 
        int ret = 0; 
        int time = 3;
        
        int connfd = -1;
        
        // 存放编码 TLV 完成的 req
        unsigned char    *msgKey_Req_Data = NULL;   
        int             msgKey_Req_DataLen = 0;
        
        // 存放编码 TLV 完成的 res
        unsigned char    *msgKey_Res_Data = NULL;
        int             msgKey_Res_DataLen = 0;
        
        MsgKey_Res         *pStruct_Res = NULL;
        int             iType = 0;
    
        // 初始化密钥请求结构体
        MsgKey_Req msgKey_req;
        msgKey_req.cmdType = KeyMng_NEWorUPDATE;
        strcpy(msgKey_req.clientId, pCltInfo->clientId);
        strcpy(msgKey_req.AuthCode, pCltInfo->AuthCode);
        strcpy(msgKey_req.serverId, pCltInfo->serverId);    
        
        // 产生随机数         abcdefg
        for (i = 0; i < 64; i++) {
            msgKey_req.r1[i] = 'a' + i;    
        }
        
        // 编码密钥请求 结构体 req
        ret = MsgEncode(&msgKey_req, ID_MsgKey_Req, &msgKey_Req_Data, &msgKey_Req_DataLen);
        if (ret != 0) {        
            KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func MsgEncode() err:%d", ret);
            goto END;    
        }
        
        // 初始化建立连接函数
        ret = sckClient_init();
        if (ret != 0) {
            KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func sckClient_init() err:%d", ret);
            goto END;    
        }
            
        // 创建连接。
        ret = sckClient_connect(pCltInfo->serverip, pCltInfo->serverport, time, &connfd);
        if (ret != 0) {
            KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func sckClient_connect() err:%d", ret);
            goto END;    
        }
            
        // 发送数据
        ret = sckClient_send(connfd, time, msgKey_Req_Data, msgKey_Req_DataLen);
        if (ret != 0) {
            KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func sckClient_send() err:%d", ret);
            goto END;    
        }
            
        // ---- 等待服务器回发数据
        
        // 接收数据
        ret = sckClient_rev(connfd, time, &msgKey_Res_Data, &msgKey_Res_DataLen);
        if (ret != 0) {
            KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func sckClient_rev() err:%d", ret);
            goto END;    
        }    
        
        // 解码密钥应答 结构体 res ---> rv r2
        ret = MsgDecode(msgKey_Res_Data, msgKey_Res_DataLen, (void **)&pStruct_Res, &iType);
        if (ret != 0) {
            KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "func MsgDecode() err:%d", ret);
            goto END;    
        }    
        
        if (pStruct_Res->rv != 0) {
            ret    = -1;
            goto END;
        } else if (pStruct_Res->rv == 0) {
            ret = 0;
            printf("---当前生成的密钥编号为:%d
    ", pStruct_Res->seckeyid);    
            goto END;
        }
        
        // --利用 r1 r2 生成密钥
        
        // --写入共享内存。
        
    END:
        if (msgKey_Req_Data != NULL) 
            MsgMemFree((void **)&msgKey_Req_Data, 0);
        if (msgKey_Res_Data != NULL) 
            MsgMemFree((void **)&msgKey_Res_Data, 0);
        if (pStruct_Res != NULL) 
            MsgMemFree((void **)&pStruct_Res, iType);
        
        return ret;    
    }
    keymngclientop.c

    8、密钥协商服务器-框架梳理

    》密钥协商服务器:

        void *callback(void *arg)
        {
            // 接收客户端 密钥请求报文 --- TLV req
    
            // 解码客户端 密钥请求报文 ---> cmdType
    
            switch(cmdType) {
                case 密钥协商:
                    mngServer_Agree();
              break;
                case 密钥校验:
                    mngServer_Check();
                    break;
                case 密钥注销:
                    mngServer_Revoke();
              break;
    defaultbreak; } // 发送应答报文 } keymngserver.c -------业务逻辑 { // 服务器信息初始化。 // 监听客户端连接请求 while(1) { // 启动线程 与客户端 进行通信 fd pthread_create(, (void *)fd); } }

    注意:服务器与客户端区别的主要原因是:服务器必须接收数据包解码以后才知道客户端想做什么,而客户端在发送数据之前就清楚自己要干什么!

    服务器的发送应答报文放到Agree函数外边,所以服务器的Agree函数的接口与客户端Agree函数接口不同。(两种都可以,根据需求都可以做。)

        keymngserverop.c         keymngserverop.h        功能实现
        实现 服务器信息初始化。        服务器信息初始化声明。             
        实现 服务器密钥协商。        。。。。
        实现 服务器密钥校验。   
        实现 服务器密钥注销。

        struct serverInfo {serverIp, serverPort, serverID, shmkey, shmid, maxnode, dbuser, dbpasswd, dbname, maxnum} 不变

        int MngServer_Agree(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen);
        {
            // 生成随机数 r2
    
            // 结合 r1 r2 生成密钥  ---> 成功、失败 rv
    
            // 组织 应答结构体 res : rv r2 clientId serverId  seckeyid
    
            // 写共享内存
    
            // 写数据库
    
            // 编码应答报文  传出
        }

    9、密钥协商服务器-业务逻辑实现

    >keymngserverop.h

    // keymngserverop.h
    #ifndef _KEYMNG_ServerOp_H_
    #define _KEYMNG_ServerOp_H_
    
    #include "keymng_msg.h"
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    //keymngserver 错误码
    
    #define        MngSvr_OK                0        //正确
    #define        MngSvr_ParamErr            301        //输入参数失败
    #define        MngSvr_NoNetPointErr    302        //共享内存中,没有找到网点信息
    #define        MngSvr_NodeMaxCount        303        //共享内存中,超过最大网点
    #define        MngSvr_CheckErr            304        //共享内存中,超过最大网点
    
    typedef struct _MngServer_Info
    {
        char            serverId[12];    //服务器端编号
        
        //数据库连接池句柄    
        char            dbuse[24];         //数据库用户名
        char            dbpasswd[24];     //数据库密码
        char            dbsid[24];         //数据库sid
        int                dbpoolnum;         //数据库池 连接数
        
        char            serverip[24];
        int             serverport;
        
        //共享内存配置信息
        int                maxnode; //最大网点树 客户端默认1个
        int             shmkey;     //共享内存keyid 创建共享内存时使用     
        int             shmhdl; //共享内存句柄    
    }MngServer_Info;
    
    
    
    //初始化服务器 全局变量
    int MngServer_InitInfo(MngServer_Info *svrInfo);
    
    int MngServer_Quit(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen);
    
    //服务端 密钥协商应答流程
    int MngServer_Agree(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen);
    //int keymngsever_agree(MngServer_Info *pServferInfo, MsgKey_Req *pMsgKeyReq ,  unsigned char **pMsgKeyResData, int *pMsgKeyResDataLen)
       
    int MngServer_Check(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen);
    
    int MngServer_Revoke(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen);
    
    int MngServer_view(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen);
    
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif
    keymngserverop.h

    >keymngserverop.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include "keymngserverop.h"
    #include "keymng_msg.h"
    #include "keymnglog.h" 
    
    
    int MngServer_InitInfo(MngServer_Info *svrInfo)
    {
        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;
        
        return 0;    
    }
    
    int MngServer_Agree(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen)
    {
        
        return 0;    
    }
    keymngserverop.c

    >keymngserver.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <pthread.h>
     
    #include "poolsocket.h"  
    #include "keymngserverop.h"
    #include "keymng_msg.h"
    #include "keymnglog.h"  
    
    MngServer_Info serverInfo;
     
    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) {
    
            //服务器端端接受报文
            ret = sckServer_rev(connfd, timeout, &out, &outlen); 
            if (ret == Sck_ErrPeerClosed) {
                // 检测到 对端关闭,关闭本端。
                printf("----------------ErrPeerClosed 关闭服务器
    ");
                break;
            } else if (ret == Sck_ErrTimeOut) {
                printf("---服务器检测到客户端发送数据 超时 
    ");
                continue;
            } else if (ret != 0) {
                printf("未知错误
    ");
                break;
            }
    
            // 解码客户端 密钥请求报文 ---> cmdType
            ret = MsgDecode(out, outlen, (void **)&pStruct_req, &iType);
            if (ret != 0) {
                KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "MsgDecode() err:%d", ret);    
                return ret;    
            }
    
            switch(pStruct_req->cmdType) {
                case KeyMng_NEWorUPDATE:
                    ret = MngServer_Agree(&serverInfo, pStruct_req, &res_outData, &res_outDataLen);
                /*
                case 密钥校验:
                    mngServer_Agree();
                    
                case 密钥注销:
                    mngServer_Agree();
                    */
                default:
                    break;
            }
            if (ret != 0) {        
                KeyMng_Log(__FILE__, __LINE__, KeyMngLevel[4], ret, "MngServer_Agree() err:%d", ret);                
            }
    
             //服务器端发送报文
            ret = sckServer_send(connfd, timeout, res_outData, res_outDataLen);
             if (ret == Sck_ErrPeerClosed) {
                // 检测到 对端关闭,关闭本端。
                printf("---ErrPeerClosed 
    ");
                break;
            } else if (ret == Sck_ErrTimeOut) {
                printf("---服务器检测到本端发送数据 超时 
    ");
                continue;
            } else if (ret != 0) {
                printf("未知错误
    ");
                break;
            }
        }
        
        sckServer_close(connfd);
        
         return NULL;
    }
    
    
    int main(void)
    {
        int listenfd;
        int ret = 0;
        
        int timeout = 3;
        int connfd = -1;
        
        pthread_t pid;
        
        // 服务器信息初始化。
        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) {
            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();
    
        return 0;    
    }
    keymngserver.c

    >报错1:程序中有游离的“357”

    >报错2:[ERRNO is 98]func bind() err

    端口占用问题;>ps aux | grep keymngserver查看pid;然后kill pid

    >vi makefile

    .PHONY:clean all
    
    WORKDIR=.
    VPATH = ./src
    
    CC=gcc
    CFLGS= -Wall -g -I$(WORKDIR)/inc/
    LIBFLAG = -L$(HOME)/lib
    
    
    BIN = keymngclient  keymngserver 
    
    
    all:$(BIN)
    #myipc_shm.o keymng_shmop.o
    keymngclient:keymngclient.o  keymnglog.o  keymngclientop.o  
        $(CC) $(LIBFLAG) -lpthread -litcastsocket -lmessagereal $^ -o $@ 
    
    #myipc_shm.o  keymng_shmop.o  keymng_dbop.o         -lclntsh  -licdbapi
    keymngserver:keymngserver.o  keymngserverop.o  keymnglog.o  
        $(CC) $(LIBFLAG) $^ -o $@ -lpthread -litcastsocket -lmessagereal  
     
    #testdbapi:testdbapi.o  
    #    $(CC) $(LIBFLAG) $^ -o $@ -lpthread  -lclntsh  -licdbapi
            
    %.o:%.c
        $(CC) $(CFLGS) -c $< -o $@    
    
    clean:
        rm -f *.o $(BIN)
        
    makefile

    >make

    >./keymngclient

    打开另一个终端,执行>./keymngserver,

    原终端情况:

    服务器端情况:

    10、密钥协商服务器-Agree功能实现

    >vi keymngserver.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include "keymngserverop.h"
    #include "keymng_msg.h"
    #include "keymnglog.h" 
    
    static int    seckeyid = 100;
    
    int MngServer_InitInfo(MngServer_Info *svrInfo)
    {
        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;
        
        return 0;    
    }
    
    int MngServer_Agree(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen)
    {
        int ret = 0;
        int i = 0;
        MsgKey_Res msgKey_Res;
        
        // --结合 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;            //
        }    
        msgKey_Res.seckeyid = seckeyid++;
    
        // --写共享内存
    
        // --写数据库
    
        // 编码应答报文  传出
        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;    
    }
    keymngserverop.c

    注意:结合 r1 r2 生成密钥、写共享内存、写数据库 暂不实现。

    >make

    >./keymngclient

    打开另一个终端,执行>./keymngserver,分别查看终端执行情况。

    客户端情况:(输入:1)

    点击“Enter”后,再次输入:1

    服务器端情况:

    11、总结

    》客户端:keymngclient.c—负责业务逻辑;keymngclientop.c—负责功能实现

    》服务器:keymngserver.c—负责业务逻辑;keymngserverop.c—负责功能实现

    注意:服务器与客户端区别的主要原因是:服务器必须接收数据包解码以后才知道客户端想做什么,而客户端在发送数据之前就清楚自己要干什么!

    在学习安全传输平台项目总结了笔记,并分享出来。有问题请及时联系博主:Alliswell_WP,转载请注明出处。

  • 相关阅读:
    [转载]IT名企的薪资情况
    [转载]基于Oracle的高性能动态SQL程序开发(一)
    [转载]基于Oracle的高性能动态SQL程序开发(二)
    [转载]从Google身上可以学到的14个东西
    两篇励志故事
    《RedHat9系统管理》读书笔记 下载
    Linux各种版本下载
    Hibernate介绍, 语法 和 Hibernate的基本元素
    android中系统日期时间的获取
    关于Struts框架简介
  • 原文地址:https://www.cnblogs.com/Alliswell-WP/p/CPlusPlus_SecureTransmissionPlatform_Project05.html
Copyright © 2011-2022 走看看