OpenHarmony深度解读之分布式软总线:auth_interface.c文件部分源码解析

一、概述

auth_interface.c文件主要是提供一些设备间进行身份认证所需要的接口,如认证会话的管理、会话密钥的管理、HiChain的管理等。下面本文将对auth_interface.c文件的部分代码进行分析,因为有的代码会涉及到另一个模块的内容,那一块将会在接下来的文章中进行分析。

二、源码分析

auth_interface.h文件分析:

arduino 复制代码
#ifndef LITE_AUTH_INTERFACE_H   //头文件守卫,防止重复包含
#define LITE_AUTH_INTERFACE_H
#include "auth_conn.h"
#define AUTH_DEFAULT_ID "default"   //默认认证ID
#define AUTH_DEFAULT_ID_LEN 7       //默认认证ID长度
#define AUTH_SESSION_KEY_LEN 16     //认证会话密钥长度
#define AUTH_SESSION_KEY_MAX_NUM 2  //认证会话密钥最大数量
#define AUTH_SESSION_MAX_NUM 2      //认证会话最大数量
/*会话密钥*/
typedef struct SessionKey {
    char key[AUTH_SESSION_KEY_LEN];//会话密钥
    int index;//会话密钥索引
    int fd;//通信套接字描述符
} SessionKey;
/*会话密钥结点*/
typedef struct SessionKeyNode {
    List head;
    SessionKey sKey;//会话密钥结构体
} SessionKeyNode;
/*认证会话信息结构体*/
typedef struct AuthSession {
    int isUsed;//指示当前认证会话是否被使用,0为未被使用,1为已被使用
    long long seqId;//数据包序列号
    uint32_t sessionId;//会话id
    AuthConn *conn;//连接信息
} AuthSession;
void AuthInterfaceOnDataReceived(const AuthConn *conn, int module, long long seqId, const char *data, int dataLen);//处理新数据的函数接口
SessionKey *AuthGetSessionKeyByIndex(int index);//通过索引获取设备认证过程中的会话密钥
SessionKey *AuthGetNewSessionKey(void);//获取新认证会话密钥
void ClearSessionKeyByFd(int fd);//根据fd清除会话密钥
#endif

DD一下: 欢迎大家关注公众号<程序猿百晓生>,可以了解到一下知识点。

erlang 复制代码
1.OpenHarmony开发基础
2.OpenHarmony北向开发环境搭建
3.鸿蒙南向开发环境的搭建
4.鸿蒙生态应用开发白皮书V2.0 & V3.0
5.鸿蒙开发面试真题(含参考答案) 
6.TypeScript入门学习手册
7.OpenHarmony 经典面试题(含参考答案)
8.OpenHarmony设备开发入门【最新版】
9.沉浸式剖析OpenHarmony源代码
10.系统定制指南
11.【OpenHarmony】Uboot 驱动加载流程
12.OpenHarmony构建系统--GN与子系统、部件、模块详解
13.ohos开机init启动流程
14.鸿蒙版性能优化指南
.......

auth_interface.c文件部分代码解析:

ini 复制代码
#include "auth_interface.h"
#include "hichain.h"
#include "securec.h"
#include "auth_conn.h"
#include "bus_manager.h"
#include "os_adapter.h"
#include "wifi_auth_manager.h"
static uint32_t g_authSessionId = 1;//全局认证会话id
static List *g_sessionKeyList = NULL;//全局会话密钥链表表头
static AuthSession *g_authSessionMap = NULL;//全局认证会话表
static hc_handle g_hcHandle = NULL;//
/*
函数功能:认证会话表初始化
函数参数:无
函数返回值:
    成功:返回0
    失败:返回-1
详细:具体就是为全局认证会话表指针g_authSessionMap申请空间并初始化为0
*/
static int AuthSessionMapInit(void)
{
    if (g_authSessionMap != NULL) {
        return 0;
    }
    int len = sizeof(AuthSession) * AUTH_SESSION_MAX_NUM;
    g_authSessionMap = (AuthSession *)malloc(len);
    if (g_authSessionMap == NULL) {
        return -1;
    }
    (void)memset_s(g_authSessionMap, len, 0, len);
    return 0;
}
/*
函数功能:根据SeqId在全局会话表中查找认证会话
函数参数:
    SeqId:数据包序列号
函数返回值:
    成功:返回认证会话首地址
    失败:返回NULL
详细:
*/
static AuthSession *AuthGetAuthSessionBySeqId(long long seqId)
{
    if (g_authSessionMap == NULL) {
        return NULL;
    }
    for (int i = 0; i < AUTH_SESSION_MAX_NUM; i++) {
        if (g_authSessionMap[i].isUsed == 0) {//如果该会话未被使用,则continue
            continue;
        }
        if (g_authSessionMap[i].seqId == seqId) {//查找到seqId对应的认证会话,返回该认证会话地址
            return &g_authSessionMap[i];
        }
    }
    return NULL;
}
/*
函数功能:构造新的认证会话
函数参数:
    conn:连接信息
    seqId:数据包序列号
    sessionId:会话id
函数返回值:
    成功:返回认证会话结构体地址
    失败:返回NULL
详细:
*/
static AuthSession *AuthGetNewAuthSession(const AuthConn *conn, long long seqId, uint32_t sessionId)
{
    if (conn == NULL || g_authSessionMap == NULL) {//边界检查
        return NULL;
    }
    for (int i = 0; i < AUTH_SESSION_MAX_NUM; i++) {
        if (g_authSessionMap[i].isUsed == 0) {//将未被使用的认证会话初始化
            g_authSessionMap[i].isUsed = 1;
            g_authSessionMap[i].seqId = seqId;
            g_authSessionMap[i].sessionId = sessionId;
            g_authSessionMap[i].conn = (AuthConn *)conn;
            return &g_authSessionMap[i];//返回认证会话表中首次被使用的认证会话结构体地址
        }
    }
    return NULL;
}
/*
函数功能:根据fd清除会话密钥
函数参数:
    fd:通信套接字描述符
函数返回值:无
*/
void ClearSessionKeyByFd(int fd)
{
    if (g_sessionKeyList == NULL) {//健壮性检查
        return;
    }
    bool flag = false;//查找成功的标志
    List *pos = NULL;//遍历链表的临时指针
    List *tmp = NULL;
    SessionKeyNode *node = NULL;
    LIST_FOR_EACH_SAFE(pos, tmp, g_sessionKeyList) {//遍历全局认证会话密钥链表
        node = (SessionKeyNode *)pos;
        if (node->sKey.fd == fd) {//根据fd查找到该密钥
            flag = true;
            break;
        }
    }
    if (flag) {
        ListRemoveNode(&(node->head));//将该节点从链表中移除
        free(node);
        node = NULL;
    }
    SOFTBUS_PRINT("[AUTH] ClearSessionKeyByFd(%d) ok\n", fd);
    return;
}
/*
函数功能:通过索引获取设备认证过程中的会话密钥
函数参数:
    index:密钥索引
函数返回值:
    成功:返回会话密钥的结构体地址
    失败:返回NULL
详细:
*/
SessionKey *AuthGetSessionKeyByIndex(int index)
{
    if (g_sessionKeyList == NULL) {
        return NULL;
    }
    List *pos = NULL;
    List *tmp = NULL;
    SessionKeyNode *node = NULL;
    LIST_FOR_EACH_SAFE(pos, tmp, g_sessionKeyList) {//遍历链表,查找满足条件的值
        node = (SessionKeyNode *)pos;
        if (node->sKey.index == index) {
            return &node->sKey;
        }
    }
    return NULL;
}
/*获取新认证会话密钥*/
SessionKey *AuthGetNewSessionKey(void)
{
    if (g_sessionKeyList == NULL) {
        return NULL;
    }
    List *pos = NULL;
    List *tmp = NULL;
    SessionKeyNode *node = NULL;
    SessionKey *sKey = NULL;
    LIST_FOR_EACH_SAFE(pos, tmp, g_sessionKeyList) {//遍历全局认证会话密钥链表
        node = (SessionKeyNode *)pos;
        sKey = &node->sKey;
    }
    return sKey;
}
/*
函数功能:在身份认证过程中,初始化HiChain
函数参数:
    sessionId:会话id
函数返回值:
    成功:返回0
    失败:返回-1
*/
static int AuthInitHiChain(uint32_t sessionId)
{
    SOFTBUS_PRINT("[AUTH] AuthInitHiChain begin\n");
    struct session_identity serverIdentity = {
        sessionId,
        {AUTH_DEFAULT_ID_LEN, AUTH_DEFAULT_ID},
        {AUTH_DEFAULT_ID_LEN, AUTH_DEFAULT_ID},
        0
    };
    struct hc_call_back hiChainCallback = {
        AuthOnTransmit,
        AuthGetProtocolParams,
        AuthSetSessionKey,
        AuthSetServiceResult,
        AuthConfirmReceiveRequest
    };
    g_hcHandle = get_instance(&serverIdentity, HC_ACCESSORY, &hiChainCallback);
    if (g_hcHandle == NULL) {
        return -1;
    }
    SOFTBUS_PRINT("[AUTH] AuthInitHiChain ok\n");
    return 0;
}
/*
函数功能:处理身份认证过程中接收到的数据
函数参数:
    sessionId:会话id
    data:数据负载部分首地址
    dataLen:数据长度
函数返回值:无
详细:
*/
static void AuthProcessReceivedData(uint32_t sessionId, const char *data, int dataLen)
{
    if (g_hcHandle == NULL) {
        if (AuthInitHiChain(sessionId) != 0) {//初始化HiChain
            AuthDelAuthSessionBySessionId(sessionId);//根据sessionId删除该认证会话
            return;
        }
    }
    struct uint8_buff request = {(uint8_t *)data, dataLen, dataLen};//封装request数据
    if (receive_data(g_hcHandle, &request) != HC_OK) {//在其他模块继续处理该数据包
        return;
    }
}
/*
函数功能:若数据包类型为MODULE_AUTH_SDK,则调用本函数进行处理,此函数为认证接口
函数参数:
    conn:当前连接信息
    module:数据包类型
    seqId:数据包序列号
    data:数据负载
    dataLen:负载长度
函数返回值:无
*/
void AuthInterfaceOnDataReceived(const AuthConn *conn, int module, long long seqId, const char *data, int dataLen)
{
    SOFTBUS_PRINT("[AUTH] AuthInterfaceOnDataReceived begin\n");
    if (conn == NULL || data == NULL || dataLen > PACKET_DATA_SIZE) {//若产生越界,则返回
        return;
    }
    if (AuthSessionMapInit() != 0) {//初始化认证会话表
        return;
    }
    AuthSession *auth = AuthGetAuthSessionBySeqId(seqId);//根据SeqId查找认证会话
    if (auth == NULL) {//如果不存在
        auth = AuthGetNewAuthSession(conn, seqId, g_authSessionId);//构造新的认证会话,g_authSessionId初值为1
        if (auth == NULL) {
            return;
        }
        ++g_authSessionId;//全局认证会话id加1
    }
    switch (module) {
        case MODULE_AUTH_SDK://如果数据包类型是MODULE_AUTH_SDK:
            AuthProcessReceivedData(auth->sessionId, data, dataLen);//处理身份认证过程中接收到的数据
            break;
        default:
            break;
    }
    return;
}
相关推荐
Surpass余sheng军3 小时前
AI 时代下的网关技术选型
人工智能·经验分享·分布式·后端·学习·架构
遇到困难睡大觉哈哈4 小时前
HarmonyOS —— Remote Communication Kit 拦截器(Interceptor)高阶定制能力笔记
笔记·华为·harmonyos
遇到困难睡大觉哈哈6 小时前
HarmonyOS —— Remote Communication Kit 定制处理行为(ProcessingConfiguration)速记笔记
笔记·华为·harmonyos
氤氲息6 小时前
鸿蒙 ArkTs 的WebView如何与JS交互
javascript·交互·harmonyos
遇到困难睡大觉哈哈6 小时前
HarmonyOS支付接入证书准备与生成指南
华为·harmonyos
赵浩生6 小时前
鸿蒙技术干货10:鸿蒙图形渲染基础,Canvas绘图与自定义组件实战
harmonyos
赵浩生6 小时前
鸿蒙技术干货9:deviceInfo 设备信息获取与位置提醒 APP 整合
harmonyos
哈哈哈笑什么6 小时前
企业级高并发分布式SpringCloud系统下,订单动态超时自动取消(最终成熟方案),使用spring-cloud-starter-stream-rabbit
分布式·spring cloud·rabbitmq
哈哈哈笑什么6 小时前
Sleuth+Zipkin 与 OpenSearch 结合是企业级分布式高并发系统的“王炸组合”
分布式·后端·spring cloud