Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to authenticate user in ONVIF?

we have network IP camera that supports ONVIF protocol. When I tried to get its PTZ configuration it gives Auth error. I am implementing this in C. Following are the request and response.

Request:

"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" 
  "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\"" 
  "xmlns:tds=\"http://www.onvif.org/ver20/ptz/wsdl\">" 
  "<soap:Body>"
  "<tds:GetNodes/>" 
  "</soap:Body>" 
  "</soap:Envelope>"

Response:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope  xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" 
                xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
                xmlns:wsa5="http://www.w3.org/2005/08/addressing" 
                xmlns:c14n="http://www.w3.org/2001/10/xml-exc-c14n#" 
                xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" 
                xmlns:ds="http://www.w3.org/2000/09/xmldsig#" 
                xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" 
                xmlns:ptzimg2="http://www.onvif.org/ver10/schema" 
                xmlns:ptzimg3="http://www.w3.org/2005/05/xmlmime" 
                xmlns:ptzimg4="http://docs.oasis-open.org/wsn/b-2" 
                xmlns:ptzimg5="http://docs.oasis-open.org/wsrf/bf-2" 
                xmlns:ptzimg6="http://docs.oasis-open.org/wsn/t-1" 
                xmlns:ptzimg1="http://www.onvif.org/ver20/ptz/wsdl" 
                xmlns:ptzimg7="http://www.onvif.org/ver20/imaging/wsdl" 
                xmlns:ter="http://www.onvif.org/ver10/error">

<SOAP-ENV:Body>
    <SOAP-ENV:Fault>
        <SOAP-ENV:Code>
            <SOAP-ENV:Value>
                SOAP-ENV:Sender
            </SOAP-ENV:Value>
            <SOAP-ENV:Subcode>
                <SOAP-ENV:Value>
                    ter:NotAuthorized
                </SOAP-ENV:Value>
            </SOAP-ENV:Subcode>
        </SOAP-ENV:Code>
        <SOAP-ENV:Reason>
            <SOAP-ENV:Text xml:lang="en">
                Sender Not Authorized
            </SOAP-ENV:Text>
        </SOAP-ENV:Reason>
        <SOAP-ENV:Node>
            http://www.w3.org/2003/05/soap-envelope/node/ultimateReceiver
        </SOAP-ENV:Node>
        <SOAP-ENV:Role>
            http://www.w3.org/2003/05/soap-envelope/role/ultimateReceiver
        </SOAP-ENV:Role>
        <SOAP-ENV:Detail>
            The action requested requires authorization and the sender is not authorized
        </SOAP-ENV:Detail>
    </SOAP-ENV:Fault>
</SOAP-ENV:Body>

How can I authenticate user? Thanks

like image 466
Sarfraz Ahmed Avatar asked May 29 '12 06:05

Sarfraz Ahmed


2 Answers

those commands which required authentication. Their authentication headers can be added like this.

 snprintf(postData, sizeof(postData),
          "<?xml version=\"1.0\" encoding=\"utf-8\"?>" 
          "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://www.w3.org/2003/05/soap-envelope\"" 
          "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\""  
          "xmlns:tds=\"http://www.onvif.org/ver20/ptz/wsdl\">" 
          "<SOAP-ENV:Header><wsse:Security><wsse:UsernameToken>" 
          "<wsse:Username>%s</wsse:Username>" 
          "<wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-"
          "200401-wss-username-token-profile-1.0#PasswordDigest\">"
              "%s</wsse:Password><wsse:Nonce>%s</wsse:Nonce>" 
          "<wsu:Created>%s</wsu:Created></wsse:UsernameToken>"
          "</wsse:Security></SOAP-ENV:Header><SOAP-ENV:Body>" 
          "<tds:GetNodes>" 
          "</SOAP-ENV:Body></SOAP-ENV:Envelope>", 
          username, base64EncDigest, nonce_char, time_char);
like image 163
Sarfraz Ahmed Avatar answered Sep 24 '22 18:09

Sarfraz Ahmed


You can use gSoap with WSSE plugin to generate C++ client proxy from OnVif WDSL that you require.

Do that greatly simplified my work. Here is an example of calling GetVideoEncoderConfiguration and reading response.

_media__GetVideoEncoderConfigurations query;
_media__GetVideoEncoderConfigurationsResponse response;

soap_wsse_add_Security(&mediaProxy);
soap_wsse_add_UsernameTokenDigest(&mediaProxy, NULL, m_username.c_str(), m_password.c_str());

if(mediaProxy.GetVideoEncoderConfigurations(&query, &response) == SOAP_OK)
{
    LogSuccess("GetVideoEncoderConfigurations");
    for(auto it = response.Configurations.begin(); it != response.Configurations.end(); ++it)
    {
        onvif__VideoEncoderConfiguration* videoConf = *it;
        log(I3) << "Name= " << videoConf->Name << ", Encoding=" << videoConf->Encoding << ", Resolution=" << videoConf->Resolution->Width << "x" << videoConf->Resolution->Height;
    }
}
else
    LogError("GetVideoEncoderConfigurations", soap_faultdetail(&mediaProxy));

So no manually creating soap messages. gSOAP generated code takes care of that in lower layer. Of course, it takes mi 2 days to generate working code with wsse support, but still it was probably 10 times faster the to do it manualy. If you are interested in further information you can contact me.

like image 26
DaNY Avatar answered Sep 22 '22 18:09

DaNY