Onvif implementation on Linux devices 16: Implementing Onvif authentication

2013-09-30 16:39:27

Today, I finally passed the authentication process through debugging, and the detailed records are as follows:
1 Principle

Chapter 6 in the ONVIF_WG-APG-Application_Programmer's_Guide.pdf document describes the onvif encryption method. The authentication mechanism of Soap communication is WS_UsernameToken, and the stream encryption method is HTTPS. This article only studies the WS_UsernameToken method.

      We know that onvif's user authentication is based on WS_UsernameToken, and the password is Digest instead of plain text. First, let's look at a message with user authentication information:

The so-called WS_UsernameToken encryption is to include the username, password, Nonce, and Created in the header. If you replace #passwordDigest with #passwordText, the password is in plain text. Of course onvif said that the password is Digest.

We know the username and password, so how to verify it? The document mentions the formula for obtaining Digest:

Digest = B64ENCODE( SHA1( B64DECODE( Nonce ) + Date + Password ) )


2 achieve

Now that we know what WS_UsernameToken is, let's take a look at how to implement verification. It is recommended to use gsoap's wsseapi plug-in to achieve this, which is definitely the most convenient method. The detailed steps are as follows:

1 The function prototypes involved in authentication are defined in devicemgmt.wsdl, so it must be used to generate onvif.h

./wsdl2h -s -c  -t WS-typemap.dat -o onvif.h  remotediscovery.wsdl devicemgmt.wsdl media.wsdl

The generated result is onvif.h

2 Modify onvif.h

The onvif.h file generated in the previous step did not open wsse.h, resulting in the lack of definition of the wsse__Security data segment in the SOAP_ENV__Header structure in the final generated code, and the authentication command cannot be performed. It must be modified as follows:

#import "wsse.h"

3 Run soapcpp2

The header file in /gsoap-2.8/gsoap/import is used, and the import path must be specified.

./soapcpp2  -c -C -L -x -I../gsoap2.8/gsoap/import  onvif.h

4 Compilation Instructions

(1) Files used for gsoap authentication: dom.c wsseapi.c smdevp.c mecevp.c threads.c wsaapi.c, and corresponding header files. These files are generally in \gsoap-2.8\gsoap\plugin\, copy these files to the compilation directory separately, and do not copy any irrelevant files.

(2) The compile switch -DWITH_DOM -DWITH_OPENSSL must be added in the makefile

(3) The wsse series functions must be linked to the standard openssl library: libssl.so, libcrypto.so. You can download the OPENSSL1.0.0 software package compilation.

I found libssl.so.0.9.8 exists on the server, the path is as follows: /work/mv_pro_5.0/montavista/pro/devkit/arm/v5t_le/target/usr/lib.

/montavista/pro/devkit/arm/v5t_le/target/usr/include/openssl, here is the corresponding header file.

After trying, the library is for the x86 platform and cannot run on the extension. Finally, find the cross-compiled library files: libssl.so.1.0.0, libcrypto.so.1.0.0, and replace them with the above path respectively. In addition, the header file in the openssl1.0.0 software package must be used to replace the above path, otherwise the linked library will be version 1.0.0, and the data structure when the program is compiled is still version 0.9.8, causing the program to run. Refers to an error crash, and generally reports an error in freeing pointers.

The reason why the openssl1.0.0 header file must be replaced in the cross-toolchain directory: because the file headers in the openssl toolkit are all like #include <openssl/opensslconf.h>. <>Included files are first searched in the system search path, and then in the current directory, so it is useless even if these header files are copied to the compilation directory.

(4) When linking ssl and crypto library files, the index file libssl.so--> libssl.so.1.0.0 libcrypto.so--> libcrypto.so.1.0.0 must be provided, otherwise it will be automatically linked to the server The x86 version library file cannot be run on the extension.

5 Run the makefile to generate searchOnvif.


3 Introduction to working directory

My working directory file is as follows:

The Makefile is as follows:

MVTOOL_DIR = /work/mv_pro_5.0/montavista/pro/devkit/arm/v5t_le/bin

CC = $(MVTOOL_DIR)/arm_v5t_le-gcc

#CC = gcc  -DWITH_NONAMESPACES

INCLUDE = -I. -Iplugin -Iinclude/gsoap/import

CFLAGS = -DWITH_NONAMESPACES -DWITH_DOM -DWITH_OPENSSL

CLIENT_OBJS = soapC.o stdsoap2.o soapClient.o md5c.o uuid32.o dom.o \

plugin/wsseapi.o plugin/smdevp.o plugin/mecevp.o plugin/threads.o plugin/wsaapi.o  \

ipclist.o searchOnvif.o 

all: client

client: $(CLIENT_OBJS)

      $(CC) $(CFLAGS) $(INCLUDE) -o searchOnvif $(CLIENT_OBJS) -lcrypto -lssl

      $(MVTOOL_DIR)/arm_v5t_le-strip searchOnvif

.c.o:

      $(CC) $(CFLAGS) $(INCLUDE) -c -o $@ $<

clean: 

      rm -f *.o

      rm -f plugin/*.o

      rm -f searchOnvif

 
4 code implementation

After tuning, I found out that gsoap is really easy to use for authentication, as long as there is one function command, everything will be fine.

/* 3 Use the authentication command to query the media information for the specified IPC*/

    struct soap *soap; //soap environment variable          

    soap = soap_new(); //Apply for variable space for soap and initialize it

    if(soap==NULL)

    {

        printf("%s : %d, can't create new soap! \n",__FUNCTION__, __LINE__);

        return -1;

    }   

    soap_set_namespaces(soap, namespaces); //Set the namespaces of soap   

    /* 4---- Start getting media information ------ */  

    soap_wsse_add_UsernameTokenDigest(soap, "user", username, password);

    bret = MyGetProfiles(soap, index);

    if(bret==FALSE)

    {

        printf("--ERROR: MyGetProfiles() return false!  \n");

        return FALSE;

    }

Trials have shown that the password digest must be re-appended with each command. The reason may be that the Header will be destroyed when the response is received, resulting in the loss of the encrypted digest.

5 actual packets

charset=utf-8;
action="Home - ONVIF Mandarin"
User-Agent: JAX-WS RI 2.2.4-b01
Host: 192.168.0.240
Connection: keep-alive
Content-Length: 1676

<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope">
<S:Header>
  <wsse:Security
    xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
    xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <wsse:UsernameToken  
      xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <wsse:Username  
        xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
        admin
      </wsse:Username>
      <wsse:Password
        xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
        Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#
        PasswordDigest">vLFa0gN1dS4sgGXATF/bLux4Spk=
      </wsse:Password>
      <wsse:Nonce
        xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
        MjA3MTg3MjA=
      </wsse:Nonce>
      <wsu:Created
        xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
        2013-09-23T15:23:34Z
      </wsu:Created>
    </wsse:UsernameToken>
  </wsse:Security>
</S:Header>
<S:Body>
  <ns10:GetCapabilities
  xmlns:ns10="http://www.onvif.org/ver10/device/wsdl"  
  xmlns:ns2="http://www.onvif.org/ver10/schema"
  xmlns:ns4="WS-Addressing 1.0 Namespace"  
  xmlns:ns5="http://docs.oasis-open.org/wsn/b-2"
  xmlns:ns6="http://docs.oasis-open.org/wsrf/bf-2"  
  xmlns:ns7="http://docs.oasis-open.org/wsn/t-1"
  xmlns:ns8="http://www.w3.org/2004/08/xop/include"  
  xmlns:ns9="http://schemas.xmlsoap.org/soap/envelope/"   
  xmlns:xmime="http://www.w3.org/2005/05/xmlmime">
  <ns10:Category>All</ns10:Category>
  </ns10:GetCapabilities>
</S:Body>
</S:Envelope>

Guess you like

Origin blog.csdn.net/u012084827/article/details/19031969