在学习安全传输平台项目总结了笔记,并分享出来。有问题请及时联系博主: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.c和myipc_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目录下。
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; }
>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 查看:
密钥查看。 建立连接、封装req结构体、编码、发送、接收、解码、生成密钥、写共享内存。
_View();
。。。。
}
将结果展示给用户。
》模块划分:
业务逻辑:
keymngclient.c
业务功能:
keymngclientop.c --> keymngclientop.h
实现 客户端信息初始化。 客户端信息初始化声明。
实现 客户端密钥协商。 。。。。
实现 客户端密钥校验。
struct clientInfo { serverIp, serverPort, clientID, serverID, Autocode, shmkey, shmid, maxnode }
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放入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; }
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("\n /*************************************************************/"); printf("\n /*************************************************************/"); printf("\n /* 1.密钥协商 */"); printf("\n /* 2.密钥校验 */"); printf("\n /* 3.密钥注销 */"); printf("\n /* 4.密钥查看 */"); printf("\n /* 0.退出系统 */"); printf("\n /*************************************************************/"); printf("\n /*************************************************************/"); printf("\n\n 选择:"); scanf("%d", &nSel); while(getchar() != '\n'); //把应用程序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 \n ", 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("选项不支持\n"); break; } // 结果展示给用户。 if (ret) { printf("\n!!!!!!!!!!!!!!!!!!!!ERROR!!!!!!!!!!!!!!!!!!!!"); printf("\n错误码是:%x\n", ret); } else { printf("\n!!!!!!!!!!!!!!!!!!!SUCCESS!!!!!!!!!!!!!!!!!!!!\n"); } getchar(); } return 0; }
>keymngclientop.c
int MngClient_Agree(MngClient_Info *pCltInfo) { //组织密钥请求结构体 //编码密钥请求结构体 //初始化连接 //建立连接 //发送请求报文 //接收应答报文 //解析应答报文 //生成密钥 //写共享内存。 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; }
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("\n /*************************************************************/"); printf("\n /*************************************************************/"); printf("\n /* 1.密钥协商 */"); printf("\n /* 2.密钥校验 */"); printf("\n /* 3.密钥注销 */"); printf("\n /* 4.密钥查看 */"); printf("\n /* 0.退出系统 */"); printf("\n /*************************************************************/"); printf("\n /*************************************************************/"); printf("\n\n 选择:"); scanf("%d", &nSel); while(getchar() != '\n'); //把应用程序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 \n ", 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("选项不支持\n"); break; } // 结果展示给用户。 if (ret) { printf("\n!!!!!!!!!!!!!!!!!!!!ERROR!!!!!!!!!!!!!!!!!!!!"); printf("\n错误码是:%x\n", ret); } else { printf("\n!!!!!!!!!!!!!!!!!!!SUCCESS!!!!!!!!!!!!!!!!!!!!\n"); } getchar(); } return 0; }
>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\n", pStruct_Res->seckeyid); return 0; } // --利用 r1 r2 生成密钥 // --写入共享内存。 return ret; }
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\n", 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; }
8、密钥协商服务器-框架梳理
》密钥协商服务器:
void *callback(void *arg) { // 接收客户端 密钥请求报文 --- TLV // 解码客户端 密钥请求报文 ---> cmdType switch(cmdType) { case 密钥协商: mngServer_Agree(); break; case 密钥校验: mngServer_Check(); break; case 密钥注销: mngServer_Revoke();
break; default: break; } // 发送应答报文 } keymngserver.c 业务逻辑 { // 服务器信息初始化。 // 监听客户端连接请求 while(1) { // 启动线程 与客户端 进行通信 fd pthread_create(); } }
注意:服务器与客户端区别的主要原因是:服务器必须接收数据包解码以后才知道客户端想做什么,而客户端在发送数据之前就清楚自己要干什么!
keymngserverop.c keymngserverop.h 功能实现
实现 服务器信息初始化。 服务器信息初始化声明。
实现 服务器密钥协商。 。。。。
实现 服务器密钥校验。
实现 服务器密钥注销。
struct serverInfo {serverIp, serverPort, clientID, serverID, Autocode, shmkey, shmid, maxnode, username, passwd, dbname} 不变
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.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; }
>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 关闭服务器\n"); break; } else if (ret == Sck_ErrTimeOut) { printf("---服务器检测到客户端发送数据 超时 \n"); 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); 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 \n"); break; } else if (ret == Sck_ErrTimeOut) { printf("---服务器检测到本端发送数据 超时 \n"); continue; } else if (ret != 0) { printf("未知错误\n"); 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; }
>报错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)
>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; }
>make
>./keymngclient
打开另一个终端,执行>./keymngserver,分别查看终端执行情况。
客户端情况:(输入:1)
点击“Enter”后,再次输入:1
服务器端情况:
11、总结
》客户端:keymngclient.c—负责业务逻辑;keymngclientop.c—负责功能实现
》服务器:keymngserver.c—负责业务逻辑;keymngserverop.c—负责功能实现
注意:服务器与客户端区别的主要原因是:服务器必须接收数据包解码以后才知道客户端想做什么,而客户端在发送数据之前就清楚自己要干什么!
在学习安全传输平台项目总结了笔记,并分享出来。有问题请及时联系博主:Alliswell_WP,转载请注明出处。