2013년 4월 23일 화요일

WS-Security using gSOAP


WS-Security using gSOAP


gSOAP plug-in을 이용하여 ONVIF device service 에 WS-Security를 추가하는 방법을 설명한다.

  1. /gSOAP/bin/share/gsoap/WS/typemap.dat 에서 아래 추가 후 ONVIF-typemap.dat로 수정.
              tt = "http://www.onvif.org/ver10/schema"
                tds = "http://www.onvif.org/ver10/device/wsdl"
                trt = "http://www.onvif.org/ver10/media/wsdl"
                tev = "http://www.onvif.org/ver10/events/wsdl"
                ter = "http://www.onvif.org/ver10/error"
                dn = "http://www.onvif.org/ver10/network/wsdl"
                tptz = "http://www.onvif.org/ver20/ptz/wsdl"
                tima = "http://www.onvif.org/ver20/imaging/wsdl"
                tns1 = "http://www.onvif.org/ver10/topics"
                wsdl = "http://schemas.xmlsoap.org/wsdl/"
                wsoap12 = "http://schemas.xmlsoap.org/wsdl/soap12/"
                http = "http://schemas.xmlsoap.org/wsdl/http/"
                soapenc = "http://www.w3.org/2003/05/soap-encoding"
                soapenv = "http://www.w3.org/2003/05/soap-envelope"
                xs = "http://www.w3.org/2001/XMLSchema"
                xsi = "http://www.w3.org/2001/XMLSchema-instance"
                d = "http://schemas.xmlsoap.org/ws/2005/04/discovery"
                wsadis = "http://schemas.xmlsoap.org/ws/2004/08/addressing"
                wstop = "ttp://docs.oasis-open.org/wsn/t-1"
                wsnt = "http://docs.oasis-open.org/wsn/b-2"
                xop = "http://www.w3.org/2004/08/xop/include"
              
                wsrf_bf2 = "http://docs.oasis-open.org/wsrf/bf-2"
                wsrf_rw2 = "http://docs.oasis-open.org/wsrf/rw-2"
                wsrf_r2 = "http://docs.oasis-open.org/wsrf/r-2"
                wstop = "http://docs.oasis-open.org/wsn/t-1"
                wsnt = "http://docs.oasis-open.org/wsn/b-2"
                xop = "http://www.w3.org/2004/08/xop/include"

  2. wsdl2h -c -nonvif -Nonvif -t wsdl/ONVIF-typemap.dat -o wsdl/devicemgmt_gsoap.h wsdl/devicemgmt.wsdl

  3. devicemgmt_gsoap.h 수정
    #import "wsse.h" 추가.

  4. soapcpp2  -L -x  -S -c -I../../gSOAP/bin/share/gsoap/import/ wsdl/devicemgmt_gsoap.h

  5. 인증 처리절차 추가
    1. int security_check(struct soap *soap)
      {

          const char *username = soap_wsse_get_Username(soap);

          if(username)
          {
              sprintf(debug_buff,"request user:%s", username);
              Debug_cgi(debug_buff);
          }

        if (soap_wsse_verify_Timestamp(soap)
         || soap_wsse_verify_Password(soap, "password"))
        {
            Debug_cgi("failed to soap_wsse_verify_Password ");
            soap_wsse_delete_Security(soap);

            return soap->error;
        }


        soap_wsse_delete_Security(soap);

        Debug_cgi("success to soap_wsse_verify_Password");
        return SOAP_OK;
      }
      SOAP_FMAC5 int SOAP_FMAC6 soap_serve_request(struct soap *soap)
      {
          soap_peek_element(soap);
          // 클라이언트가 시간을 동기화할 수 있도록 허용하여 인증만료로 인한 인증실패를 피한다.
          if (soap_match_tag(soap, soap->tag, "tds:GetSystemDateAndTime"))
          {
              if ( security_check(soap) != SOAP_OK) return soap->error;
          }
         .....
         ....


  6. compile
참조 : gSOAP/gsoap-2.8/gsoap/doc/wsse/html/wsse.html
  1. include ../Rules.make

    GCC_PATH=/usr/arm/mv_pro_5.0.0/montavista/pro/devkit/arm/v5t_le/bin
    CROSS:=$(GCC_PATH)/arm_v5t_le-
    CC:=$(CROSS)gcc
    AR:=$(CROSS)ar

    RELTARGET := services
    INC_PATH= -I$(BASE_DIR)/gSOAP/bin/include -I$(LIB_PATH)/include
    CFLAGS := -Wall -g $(INC_PATH)  -DWITH_DOM -DWITH_OPENSSL

    SRC_COMMON = soapC.c soapServer.c

    SRCS    :=  $(SRC_COMMON) devicemgmt_service.c  wsaapi.c wsseapi.c threads.c dom.c smdevp.c mecevp.c
    OBJS    :=  $(SRCS:%.c=%.o)

    LIBS    =    -L$(BASE_DIR)/gSOAP/bin/lib -lgsoapssl  -lssl -lcrypto -lz -L$(LIB_PATH)/bin -lnettool

    .PHONY : clean all

    all:     release

    release:    $(RELTARGET)

    $(RELTARGET): $(OBJS)
        $(CC) $(CFLAGS) -o $@ $^ $(LIBS)

    install: release
        install $(RELTARGET) $(TARGET_CGI_PATH)

    clean:
        @rm -f $(TARGET)
        @rm -f $(OBJS)
        @rm -f $(RELTARGET)

7. 문제해결과정
            1). 문제: 인증실패시 wsseapi.c에서 soap_wsse_sender_fault_subcode() 호출하면  soap protocol error메시지가 'Plugin registry error'
               원인: 메시지 처럼 WSA plug-in 을 등록해야한다.
               해결: 플러그인 등록 함수 추가
                         soap_register_plugin(&soap, soap_wsa);
                        soap_register_plugin_arg(&soap, soap_wsse, token_handler);

            2). 문졔: CGI라 디버깅 하기가 어렵다
               해결: soap 라이브러리 컴파일시 -enalbe-debug
                    추가, 컴파일시 -DDEBUG 플래그추가 , soap_set_test_logfile() 함수 등록.

            3). 문제: __tds__GetSystemDateAndTime() 함수에서 인증이 실패된다.
               원인: 클라이언트(GMT)와 서버간(로컬시간)의 시간이 달라서 인증만료로 에러된다.
               해결: __tds__GetSystemDateAndTime() 는 인증을 하지않도록 하여 클라이언트가 시간을 동기화 하도록한다.

            4). 문제: __tds__GetHostname() 수신시 soap protocol error 메시지가 '502 bad gateway'
               원인: HostnameInformation->Extension를  초기화 하지않음.
               해결: HostnameInformation->Extension=NULL;

            5). 문제: security 인증 시퀀스를 모든 메소드에 넣으면 손이 많이 가고 지저분하다.
               해결: soap_serve_request()에서 인증을 하고 각 메소드를 처리하도록 수정.

댓글 없음:

댓글 쓰기