> 文档中心 > OpenHarmony深度解读之分布式软总线:authmanager模块(5)/设备身份认证过程

OpenHarmony深度解读之分布式软总线:authmanager模块(5)/设备身份认证过程


一、概述

本文将继续介绍设备之间的身份认证过程的相关细节,关于加密数据包的不同类型的处理。本文主要分析数据包类型为MODULE_TRUST_ENGINE的处理过程。源代码主要位于wifi_auth_manager.c文件的函数OnModuleMessageReceived()中。

二、源码分析

  1. 如果数据包类型为MODULE_TRUST_ENGINE且数据包头部flags字段为FLAG_REPLY,则调用函数 OnMsgOpenChannelReq() 进行处理。
/*函数功能:处理对端设备发来的请求消息并做相应回复函数参数:    conn:设备连接信息    seq:数据包序列号    msg:cJSON格式的数据负载函数返回值:无详细:*/void OnMsgOpenChannelReq(AuthConn *conn, long long seq, const cJSON *msg){//解析消息获取设备id(deviceId)和认证id(authId)保存在conn中    int ret = MsgGetDeviceIdUnPack(msg, conn);    if (ret != 0) { CloseConn(conn); return;    }#ifdef SOFTBUS_DEBUG    if (strcpy_s(g_peerAuthId, MAX_AUTH_ID_LEN, conn->authId) != EOK) { SOFTBUS_PRINT("[AUTH] OnMsgOpenChannelReq save peer auth id fail\n");    }#endif    DeviceInfo *localDevInfo = BusGetLocalDeviceInfo();//获取本地设备信息    if (localDevInfo == NULL) { CloseConn(conn);//关闭连接 return;    }//将deviceId打包成cJSON格式的Get消息作为回复消息    cJSON *reply = MsgGetDeviceIdPack(localDevInfo);    if (reply == NULL) { CloseConn(conn);//关闭连接 SOFTBUS_PRINT("[AUTH] OnMsgOpenChannelReq pack reply fail\n"); return;    }//构造/封装身份认证Post消息并发送给对端,MODULE_TRUST_ENGINE表示可信设备(暂定)    ret = AuthConnPostMessage(conn->fd, MODULE_TRUST_ENGINE, FLAG_REPLY, seq, reply);    if (ret != 0) { SOFTBUS_PRINT("[AUTH] OnMsgOpenChannelReq post msg fail\n"); CloseConn(conn);//关闭连接    }    cJSON_Delete(reply);    SOFTBUS_PRINT("[AUTH] OnMsgOpenChannelReq ok\n");}
  1. 下面再详细分析函数OnMsgOpenChannelReq() 的处理过程,首先在MsgGetDeviceIdUnPack函数中解析消息获取设备id(deviceId)和认证id(authId)保存在conn中。
/*函数功能:解析消息获取设备id(deviceId)和认证id(authId)函数参数:    msg:接收到的cJSON消息    conn:认证设备连接信息    cmd:命令函数返回值:    成功:返回0    失败:返回-1详细:*/static int MsgGetDeviceIdunpack(const cJSON *msg, AuthConn *conn, const char *cmd){    char *msgCmd = GetJsonString(msg, CMD_TAG);//获取消息中键为CMD_TAG的值    char *msgData = GetJsonString(msg, DATA_TAG);//获取消息中键为DATA_TAG的值    char *msgAuthId = GetJsonString(msg, DEVICEID_TAG);//获取消息中键为DEVICEID_TAG的值    //若数据包不合法,则返回-1    if (msgCmd == NULL || msgData == NULL || msgAuthId == NULL) { return -1;    }    if (strcmp(msgCmd, cmd) != 0) {//如果消息中命令与传入的命令不符,则返回-1 return -1;    }    //将消息中的msgData拷贝给认证设备连接的设备id    if (strcpy_s(conn->deviceId, sizeof(conn->deviceId), msgData) != EOK) { return -1;    }    //将消息中的msgAuthId拷贝给认证设备连接的认证id    if (strcpy_s(conn->authId, sizeof(conn->authId), msgAuthId) != EOK) { return -1;    }    return 0;}/*函数功能:解析消息获取设备id(deviceId)和认证id(authId)*/int MsgGetDeviceIdUnPack(const cJSON *msg, AuthConn *conn){    if (msg == NULL || conn == NULL) { return -1;    }    int ret = MsgGetDeviceIdunpack(msg, conn, CMD_GET_AUTH_INFO);    if (ret != 0) { return -1;    }    return 0;}
  1. 然后在函数MsgGetDeviceIdPack() 中,将deviceId打包成cJSON格式的Get消息作为回复消息。
/*函数功能:将deviceId打包成json格式的Get消息*/cJSON *MsgGetDeviceIdPack(const DeviceInfo *devInfo){    if (devInfo == NULL) { return NULL;    }    return MsgGetDeviceIdpack(devInfo, CMD_RET_AUTH_INFO);}/*函数功能:将deviceId打包成json格式的Get消息函数参数:    devInfo:本地设备信息    cmd:Get命令内容函数返回值:    成功:返回封装好的cJSON格式的消息    失败:返回NULL详细:*/static cJSON *MsgGetDeviceIdpack(const DeviceInfo *devInfo, const char *cmd){    cJSON *msg = cJSON_CreateObject();//创建一个cJSON对象    if (msg == NULL) { return NULL;    }//添加一个string类型的成员到cJSON对象msg中,键为CMD_TAG,值为传入cmd的值    if (cJSON_AddStringToObject(msg, CMD_TAG, cmd) == NULL) { cJSON_Delete(msg); return NULL;    }//添加一个string类型的成员到cJSON对象msg中,键为DATA_TAG,值为deviceId    if (cJSON_AddStringToObject(msg, DATA_TAG, devInfo->deviceId) == NULL) { cJSON_Delete(msg); return NULL;    }    return msg;}
  1. 最后在AuthConnPostMessage() 函数中,构造/封装身份认证Post消息并发送给对端,MODULE_TRUST_ENGINE表示可信设备。
/*函数功能:构造/封装身份认证Post消息并发送给对端函数参数:    fd:通信fd    module:数据包类型    flags:消息类型标记    seqNum:数据包序列号    msg:cJSON格式的数据负载函数返回值:    成功:返回0    失败:返回-1详细:*/int AuthConnPostMessage(int fd, int module, int flags, long long seqNum, const cJSON *msg){    if (msg == NULL) { return -1;    }    char *msgStr = cJSON_PrintUnformatted(msg);//将cJSON对象输出为无格式的字符串    if (msgStr == NULL) { return -1;    }    int ret = AuthConnPostBytes(fd, module, flags, seqNum, msgStr);//按字节构造身份认证连接的POST消息并通过TCP协议发送    free(msgStr);    msgStr = NULL;    return ret;}

四四频道