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




