天天看点

ONVIF Server 鉴权实现代码(服务端)

ONVIF鉴权实现代码

生成gSOAP框架代码,这个网上有很多教程,需要加入很多文件,并且需要openssl库。加入需要鉴权的文件和openssl库以后,只需要加每个接口中加入鉴权操作的代码,调用的时候就能实现鉴权。

ONVIF的鉴权分两种: HTTP Digest 和 WS-Username Token

在ONVIF Device Test Tool上可以对两种鉴权分别进行测试。

authenticate.h

#ifndef __AUTHENTICATE_H__
#define __AUTHENTICATE_H__

#include <stdio.h>
#include "stdsoap2.h"

#define AUTHREALM "IPC_CAM"

#define ACCESS_CONTROL                                                                  \
    do                                                                                  \
    {                                                                                   \
        if (onvif_access_control(soap) != SOAP_OK && http_digest_auth(soap) != SOAP_OK) \
            return 401;                                                                 \
    } while (0);

/* HTTP Digest Authentication */
int http_digest_auth(struct soap *soap);
/* WS-Username Token */
int onvif_access_control(struct soap *soap);

#endif /* __AUTHENTICATE_H__ */
           

authenticate.c

int onvif_access_control(struct soap *soap)
{
    const char *username = soap_wsse_get_Username(soap);
    if (username == NULL)
    {
        printf("username is null\r\n");
    }
    node_t *user_node = search_node(g_onvif_cfg.users, compare_user, (char *)username);
    if (!user_node)
    {
        LOG_INFO("ERROR Username is null\r\n");
        return 401;
    }
    const char *password = ((User *)(user_node->data))->password;
    if (soap_wsse_verify_Password(soap, password))
    {
        soap_wsse_delete_Security(soap);
        LOG_INFO("ERROR  Password is fault\r\n");
        return 401;
    }
    soap_wsse_delete_Security(soap);
    return SOAP_OK;
}

int http_digest_auth(struct soap *soap)
{
    if (soap->authrealm && soap->userid)
    {
        node_t *user_node = search_node(g_onvif_cfg.users, compare_user, (char *)soap->userid);
        if (user_node)
        {
            char *passwd = ((User *)(user_node->data))->password;
            if (!strcmp(soap->authrealm, AUTHREALM))
            {
                if (!http_da_verify_post(soap, passwd))
                {
                    LOG_INFO("verify ok\r\n");
                    return SOAP_OK;
                }
            }
        }
    }
    soap->authrealm = AUTHREALM;
    return 401;
}
           

继续阅读